mirror of
https://github.com/sasjs/core.git
synced 2025-12-27 13:00:05 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1380983ec | ||
|
|
b4834f9b40 | ||
|
|
1b5ad93cad | ||
|
|
f2942f2032 | ||
|
|
4198448b81 | ||
|
|
47a33452e0 | ||
|
|
fb21a0adfd | ||
|
|
e01b06b640 | ||
|
|
24380ddf26 | ||
|
|
1ef42d45af | ||
|
|
6ee13a2779 | ||
|
|
ffd2e135dc |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
node_modules
|
||||
.DS_Store
|
||||
sasjsbuild/
|
||||
sasjsresults/
|
||||
|
||||
# avoid filenames with spaces being committed to source control
|
||||
**\ **
|
||||
|
||||
456
all.sas
456
all.sas
@@ -298,9 +298,9 @@ options noquotelenmax;
|
||||
@file
|
||||
@brief Checks if a set of variables ALL exist in a data set.
|
||||
@details Returns 0 if ANY of the variables do not exist, or 1 if they ALL do.
|
||||
Usage:
|
||||
Usage:
|
||||
|
||||
%put %mf_existVarList(sashelp.class, age sex name dummyvar)
|
||||
%put %mf_existVarList(sashelp.class, age sex name dummyvar);
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_abort.sas
|
||||
@@ -325,7 +325,7 @@ options noquotelenmax;
|
||||
%let dsid=%sysfunc(open(&libds,is));
|
||||
|
||||
%if &dsid=0 %then %do;
|
||||
%put WARNING: unable to open &libds in mf_existvarlist (&dsid);
|
||||
%put %str(WARN)ING: unable to open &libds in mf_existvarlist (&dsid);
|
||||
%end;
|
||||
|
||||
%if %sysfunc(attrn(&dsid,NVARS))=0 %then %do;
|
||||
@@ -377,7 +377,7 @@ options noquotelenmax;
|
||||
%local dsid rc;
|
||||
%let dsid=%sysfunc(open(&libds,is));
|
||||
%if &dsid = 0 %then %do;
|
||||
%put WARNING: Cannot open %trim(&libds), system message below;
|
||||
%put %str(WARN)ING: Cannot open %trim(&libds), system message below;
|
||||
%put %sysfunc(sysmsg());
|
||||
-1
|
||||
%end;
|
||||
@@ -1602,7 +1602,7 @@ Usage:
|
||||
|
||||
%local count_base count_extr i i2 extr_word base_word match outvar;
|
||||
%if %length(&str1)=0 or %length(&str2)=0 %then %do;
|
||||
%put WARNING: empty string provided!;
|
||||
%put %str(WARN)ING: empty string provided!;
|
||||
%put base string (str1)= &str1;
|
||||
%put compare string (str2) = &str2;
|
||||
%return;
|
||||
@@ -1782,6 +1782,150 @@ Usage:
|
||||
%mend;
|
||||
|
||||
/** @endcond *//**
|
||||
@file
|
||||
@brief Asserts the existence (or not) of columns
|
||||
@details Useful in the context of writing sasjs tests. The results of the
|
||||
test are _appended_ to the &outds. table.
|
||||
|
||||
Example usage:
|
||||
|
||||
%mp_assertcols(sashelp.class,
|
||||
cols=name age sex,
|
||||
test=ALL,
|
||||
desc=check all columns exist
|
||||
)
|
||||
|
||||
%mp_assertcols(sashelp.class,
|
||||
cols=a b c,
|
||||
test=NONE
|
||||
)
|
||||
|
||||
%mp_assertcols(sashelp.class,
|
||||
cols=age depth,
|
||||
test=ANY
|
||||
)
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_existds.sas
|
||||
@li mf_existvarlist.sas
|
||||
@li mf_getvarlist.sas
|
||||
@li mf_wordsinstr1butnotstr2.sas
|
||||
@li mp_abort.sas
|
||||
|
||||
|
||||
@param [in] inds The input library.dataset to test for values
|
||||
@param [in] cols= The list of columns to check for
|
||||
@param [in] desc= (Testing observations) The user provided test description
|
||||
@param [in] test= (ALL) The test to apply. Valid values are:
|
||||
@li ALL - Test is a PASS if ALL columns exist in &inds
|
||||
@li ANY - Test is a PASS if ANY of the columns exist in &inds
|
||||
@li NONE - Test is a PASS if NONE of the columns exist in &inds
|
||||
@param [out] outds= (work.test_results) The output dataset to contain the
|
||||
results. If it does not exist, it will be created, with the following format:
|
||||
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
||||
|---|---|---|
|
||||
|User Provided description|PASS|Column &inds contained ALL columns|
|
||||
|
||||
|
||||
<h4> Related Macros </h4>
|
||||
@li mp_assertdsobs.sas
|
||||
@li mp_assertcolvals.sas
|
||||
@li mp_assertdsobs.sas
|
||||
|
||||
@version 9.2
|
||||
@author Allan Bowe
|
||||
|
||||
**/
|
||||
|
||||
%macro mp_assertcols(inds,
|
||||
cols=0,
|
||||
test=ALL,
|
||||
desc=0,
|
||||
outds=work.test_results
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%mp_abort(iftrue= (&syscc ne 0)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(syscc=&syscc - on macro entry)
|
||||
)
|
||||
|
||||
%local lib ds ;
|
||||
%let lib=%scan(&inds,1,%str(.));
|
||||
%let ds=%scan(&inds,2,%str(.));
|
||||
%let cols=%upcase(&cols);
|
||||
|
||||
%mp_abort(iftrue= (%mf_existds(&lib..&ds)=0)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(&lib..&ds not found!)
|
||||
)
|
||||
|
||||
%mp_abort(iftrue= (&cols=0)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(No cols provided)
|
||||
)
|
||||
|
||||
|
||||
%let test=%upcase(&test);
|
||||
|
||||
%if &test ne ANY and &test ne ALL and &test ne NONE %then %do;
|
||||
%mp_abort(
|
||||
mac=&sysmacroname,
|
||||
msg=%str(Invalid test - &test)
|
||||
)
|
||||
%end;
|
||||
|
||||
/**
|
||||
* now do the actual test!
|
||||
*/
|
||||
%local result;
|
||||
%if %mf_existVarList(&inds,&cols)=1 %then %let result=ALL;
|
||||
%else %do;
|
||||
%local targetcols compare;
|
||||
%let targetcols=%upcase(%mf_getvarlist(&inds));
|
||||
%let compare=%mf_wordsinstr1butnotstr2(
|
||||
Str1=&cols,
|
||||
Str2=&targetcols
|
||||
);
|
||||
%if %cmpres(&compare)=%cmpres(&cols) %then %let result=NONE;
|
||||
%else %let result=SOME;
|
||||
%end;
|
||||
|
||||
data;
|
||||
length test_description $256 test_result $4 test_comments $256;
|
||||
test_description=symget('desc');
|
||||
if test_description='0'
|
||||
then test_description="Testing &inds for existence of &test of: &cols";
|
||||
|
||||
test_result='FAIL';
|
||||
test_comments="&sysmacroname: &inds has &result columns ";
|
||||
%if &test=ALL %then %do;
|
||||
%if &result=ALL %then %do;
|
||||
test_result='PASS';
|
||||
%end;
|
||||
%end;
|
||||
%else %if &test=ANY %then %do;
|
||||
%if &result=SOME %then %do;
|
||||
test_result='PASS';
|
||||
%end;
|
||||
%end;
|
||||
%else %if &test=NONE %then %do;
|
||||
%if &result=NONE %then %do;
|
||||
test_result='PASS';
|
||||
%end;
|
||||
%end;
|
||||
%else %do;
|
||||
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
||||
%end;
|
||||
run;
|
||||
|
||||
%local ds;
|
||||
%let ds=&syslast;
|
||||
proc append base=&outds data=&ds;
|
||||
run;
|
||||
proc sql;
|
||||
drop table &ds;
|
||||
|
||||
%mend;/**
|
||||
@file
|
||||
@brief Asserts the values in a column
|
||||
@details Useful in the context of writing sasjs tests. The results of the
|
||||
@@ -2783,7 +2927,7 @@ run;
|
||||
%local i setds nvars;
|
||||
|
||||
%if not %sysfunc(exist(&base_ds)) %then %do;
|
||||
%put WARNING: &base_ds does not exist;
|
||||
%put %str(WARN)ING: &base_ds does not exist;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -2801,7 +2945,7 @@ select count(*) into: nvars from dictionary.columns
|
||||
where libname="%scan(%upcase(&base_ds),1)"
|
||||
and memname="%scan(%upcase(&base_ds),2)";
|
||||
%if &nvars=0 %then %do;
|
||||
%put WARNING: Dataset &base_ds has no variables! It will not be converted.;
|
||||
%put %str(WARN)ING: Dataset &base_ds has no variables, will not be converted.;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -3012,7 +3156,7 @@ quit;
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%if not %sysfunc(exist(&ds)) %then %do;
|
||||
%put WARNING: &ds does not exist;
|
||||
%put %str(WARN)ING: &ds does not exist;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -3191,18 +3335,18 @@ data &outds;
|
||||
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
set &outds;
|
||||
call symputx('REASON_CD',reason_cd,'l');
|
||||
stop;
|
||||
run;
|
||||
|
||||
%mp_abort(iftrue=(&abort=YES),
|
||||
mac=&sysmacroname,
|
||||
msg=%str(Filter issues in &inds, first was &reason_cd, details in &outds)
|
||||
)
|
||||
|
||||
%if %mf_nobs(&outds)>0 %then %do;
|
||||
%if &abort=YES %then %do;
|
||||
data _null_;
|
||||
set &outds;
|
||||
call symputx('REASON_CD',reason_cd,'l');
|
||||
stop;
|
||||
run;
|
||||
%mp_abort(
|
||||
mac=&sysmacroname,
|
||||
msg=%str(Filter issues in &inds, first was &reason_cd, details in &outds)
|
||||
)
|
||||
%end;
|
||||
%let syscc=1008;
|
||||
%return;
|
||||
%end;
|
||||
@@ -3309,13 +3453,14 @@ filename &outref temp;
|
||||
file &outref lrecl=32800;
|
||||
set &inds end=last;
|
||||
by SUBGROUP_ID;
|
||||
if _n_=1 then put '(';
|
||||
if _n_=1 then put '((';
|
||||
else if first.SUBGROUP_ID then put +1 GROUP_LOGIC '(';
|
||||
else put +2 SUBGROUP_LOGIC;
|
||||
|
||||
put +4 VARIABLE_NM OPERATOR_NM RAW_VALUE;
|
||||
|
||||
if last.SUBGROUP_ID then put ')'@;
|
||||
if last then put ')';
|
||||
run;
|
||||
%end;
|
||||
|
||||
@@ -5643,8 +5788,20 @@ proc sql
|
||||
%let contentype=%upcase(&contenttype);
|
||||
%local platform; %let platform=%mf_getplatform();
|
||||
|
||||
|
||||
/**
|
||||
* check engine type to avoid the below err message:
|
||||
* > Function is only valid for filerefs using the CACHE access method.
|
||||
*/
|
||||
%local streamweb;
|
||||
%let streamweb=0;
|
||||
data _null_;
|
||||
set sashelp.vextfl(where=(upcase(fileref)="_WEBOUT"));
|
||||
if xengine='STREAM' then call symputx('streamweb',1,'l');
|
||||
run;
|
||||
|
||||
%if &contentype=ZIP %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/zip');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -5658,7 +5815,7 @@ proc sql
|
||||
%end;
|
||||
%else %if &contentype=EXCEL %then %do;
|
||||
/* suitable for XLS format */
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/vnd.ms-excel');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -5671,7 +5828,7 @@ proc sql
|
||||
%end;
|
||||
%end;
|
||||
%else %if &contentype=XLSX %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
@@ -5686,7 +5843,7 @@ proc sql
|
||||
%end;
|
||||
%end;
|
||||
%else %if &contentype=TEXT %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/text');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -5699,7 +5856,7 @@ proc sql
|
||||
%end;
|
||||
%end;
|
||||
%else %if &contentype=CSV %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/csv');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -5729,7 +5886,8 @@ proc sql
|
||||
%mp_binarycopy(inloc="&inloc",outref=_webout)
|
||||
%end;
|
||||
|
||||
%mend;/**
|
||||
%mend;
|
||||
/**
|
||||
@file
|
||||
@brief Runs arbitrary code for a specified amount of time
|
||||
@details Executes a series of procs and data steps to enable performance
|
||||
@@ -5820,6 +5978,117 @@ quit;
|
||||
libname &lib clear;
|
||||
|
||||
|
||||
%mend;/**
|
||||
@file mp_testservice.sas
|
||||
@brief Will execute a test against a SASjs web service on SAS 9 or Viya
|
||||
@details Prepares the input files and retrieves the resulting datasets from
|
||||
the response JSON.
|
||||
|
||||
%mp_testjob(
|
||||
duration=60*5
|
||||
)
|
||||
|
||||
Note - the _webout fileref should NOT be assigned prior to running this macro.
|
||||
|
||||
@param [in] program The _PROGRAM endpoint to test
|
||||
@param [in] inputfiles= A list of space seperated fileref:filename pairs as
|
||||
follows:
|
||||
inputfiles=inref:filename inref2:filename2
|
||||
@param [in] debug= (log) Provide the _debug value
|
||||
@param [out] outlib= (0) Output libref to contain the final tables. Set to
|
||||
0 if the service output is not in JSON format.
|
||||
@param [out] outref= (0) Output fileref to create, to contain the full _webout
|
||||
response.
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_getuniquename.sas
|
||||
|
||||
@version 9.4
|
||||
@author Allan Bowe
|
||||
|
||||
**/
|
||||
|
||||
%macro mp_testservice(program,
|
||||
inputfiles=,
|
||||
debug=log,
|
||||
outlib=0,
|
||||
outref=0
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
/* parse the input files */
|
||||
%local webcount i var;
|
||||
%let webcount=%sysfunc(countw(&inputfiles));
|
||||
%do i=1 %to &webcount;
|
||||
%let var=%scan(&inputfiles,&i,%str( ));
|
||||
%local webfref&i webname&i;
|
||||
%let webref&i=%scan(&var,1,%str(:));
|
||||
%let webname&i=%scan(&var,2,%str(:));
|
||||
%end;
|
||||
|
||||
%local fref1 ;
|
||||
%let fref1=%mf_getuniquefileref();
|
||||
filename _webout "%sysfunc(pathname(work))/%mf_getuniquename().txt";
|
||||
|
||||
%local platform;
|
||||
%let platform=%mf_getplatform();
|
||||
%if &platform=SASMETA %then %do;
|
||||
proc stp program="&program"
|
||||
%do i=1 %to &webcount;
|
||||
%if &webcount=1 %then %do;
|
||||
_webin_fileref="&&webref&i"
|
||||
_webin_name="&&webname&i"
|
||||
%end;
|
||||
%else %do;
|
||||
_webin_fileref&i="&&webref&i"
|
||||
_webin_name&i="&&webname&i"
|
||||
%end;
|
||||
%end;
|
||||
_webin_file_count="&webcount"
|
||||
_debug="&debug";
|
||||
outputfile=_webout;
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
infile _webout;
|
||||
file &fref1;
|
||||
input;
|
||||
length line $10000;
|
||||
if index(_infile_,'>>weboutBEGIN<<') then do;
|
||||
line=tranwrd(_infile_,'>>weboutBEGIN<<','');
|
||||
put line;
|
||||
end;
|
||||
else if index(_infile_,'>>weboutEND<<') then do;
|
||||
line=tranwrd(_infile_,'>>weboutEND<<','');
|
||||
put line;
|
||||
stop;
|
||||
end;
|
||||
else put _infile_;
|
||||
run;
|
||||
data _null_;
|
||||
infile &fref1;
|
||||
input;
|
||||
put _infile_;
|
||||
run;
|
||||
%if &outlib ne 0 %then %do;
|
||||
libname &outlib json (&fref1);
|
||||
%end;
|
||||
%if &outref ne 0 %then %do;
|
||||
filename &outref temp;
|
||||
%mp_binarycopy(inref=_webout,outref=&outref)
|
||||
%end;
|
||||
filename _webout clear;
|
||||
|
||||
%end;
|
||||
%else %if &platform=SASVIYA %then %do;
|
||||
|
||||
%end;
|
||||
%else %do;
|
||||
%put %str(ERR)OR: Unrecognised platform: &platform;
|
||||
%end;
|
||||
|
||||
filename _webout clear;
|
||||
|
||||
%mend;/**
|
||||
@file mp_testwritespeedlibrary.sas
|
||||
@brief Tests the write speed of a new table in a SAS library
|
||||
@@ -6105,16 +6374,81 @@ alter table &libds modify &var char(&len);
|
||||
|
||||
%mp_createconstraints(inds=&dsconst,outds=&dsconst._addd,execute=YES)
|
||||
|
||||
%mend;
|
||||
/**
|
||||
@file
|
||||
@brief Used to validate variables in a dataset
|
||||
@details Useful when sanitising inputs, to ensure that they arrive with a
|
||||
certain pattern.
|
||||
Usage:
|
||||
|
||||
data test;
|
||||
infile datalines4 dsd;
|
||||
input;
|
||||
libds=_infile_;
|
||||
%mp_validatecol(libds,LIBDS,is_libds)
|
||||
datalines4;
|
||||
some.libname
|
||||
!lib.blah
|
||||
%abort
|
||||
definite.ok
|
||||
not.ok!
|
||||
nineletrs._
|
||||
;;;;
|
||||
run;
|
||||
|
||||
@param [in] incol The column to be validated
|
||||
@param [in] rule The rule to apply. Current rules:
|
||||
@li LIBDS - matches LIBREF.DATASET format
|
||||
@param [out] outcol The variable to create, with the results of the match
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquename.sas
|
||||
|
||||
@version 9.3
|
||||
**/
|
||||
|
||||
%macro mp_validatecol(incol,rule,outcol);
|
||||
|
||||
/* tempcol is given a unique name with every invocation */
|
||||
%local tempcol;
|
||||
%let tempcol=%mf_getuniquename();
|
||||
|
||||
%if &rule=ISNUM %then %do;
|
||||
/*
|
||||
credit SØREN LASSEN
|
||||
https://sasmacro.blogspot.com/2009/06/welcome-isnum-macro.html
|
||||
*/
|
||||
&tempcol=input(&incol,?? best32.);
|
||||
if missing(&tempcol) then &outcol=0;
|
||||
else &outcol=1;
|
||||
drop &tempcol;
|
||||
%end;
|
||||
%else %if &rule=LIBDS %then %do;
|
||||
/* match libref.dataset */
|
||||
if _n_=1 then do;
|
||||
retain &tempcol;
|
||||
&tempcol=prxparse('/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i');
|
||||
if missing(&tempcol) then do;
|
||||
putlog "%str(ERR)OR: Invalid expression for LIBDS";
|
||||
stop;
|
||||
end;
|
||||
drop &tempcol;
|
||||
end;
|
||||
if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
|
||||
else &outcol=0;
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
/**
|
||||
@file
|
||||
@brief Creates a zip file
|
||||
@details For DIRECTORY usage, will ignore subfolders. For DATASET usage,
|
||||
provide a column that contains the full file path to each file to be zipped.
|
||||
provide a column that contains the full file path to each file to be zipped.
|
||||
|
||||
%mp_zip(in=myzips,type=directory,outname=myDir)
|
||||
%mp_zip(in=/my/file/path.txt,type=FILE,outname=myFile)
|
||||
%mp_zip(in=SOMEDS,incol=FPATH,type=DATASET,outname=myFile)
|
||||
%mp_zip(in=myzips,type=directory,outname=myDir)
|
||||
%mp_zip(in=/my/file/path.txt,type=FILE,outname=myFile)
|
||||
%mp_zip(in=SOMEDS,incol=FPATH,type=DATASET,outname=myFile)
|
||||
|
||||
If you are sending zipped output to the _webout destination as part of an STP
|
||||
be sure that _debug is not set (else the SPWA will send non zipped content
|
||||
@@ -6256,7 +6590,7 @@ run;
|
||||
%end;
|
||||
|
||||
%if &syscc ge 4 %then %do;
|
||||
%put WARNING: SYSCC=&syscc, exiting &sysmacroname;
|
||||
%put %str(WARN)ING: SYSCC=&syscc, exiting &sysmacroname;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -6615,7 +6949,7 @@ run;
|
||||
run;
|
||||
|
||||
%if %length(&open_passthrough)>0 %then %do;
|
||||
%put WARNING: Passthrough option for postgres not yet supported;
|
||||
%put %str(WARN)ING: Passthrough option for postgres not yet supported;
|
||||
%return;
|
||||
%end;
|
||||
%else %do;
|
||||
@@ -6738,8 +7072,8 @@ run;
|
||||
%return;
|
||||
%end;
|
||||
%else %do;
|
||||
%put WARNING: Engine &engine is currently unsupported;
|
||||
%put WARNING- Please contact your support team.;
|
||||
%put %str(WARN)ING: Engine &engine is currently unsupported;
|
||||
%put %str(WARN)ING- Please contact your support team.;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7431,7 +7765,7 @@ data _null_;
|
||||
putlog (_all_)(=);
|
||||
run;
|
||||
%if &checktype = SASLibrary %then %do;
|
||||
%put WARNING: Library (&liburi) already exists with libname (&libname) ;
|
||||
%put %str(WARN)ING: Library (&liburi) already exists with libname (&libname);
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7446,7 +7780,7 @@ data _null_;
|
||||
putlog (_all_)(=);
|
||||
run;
|
||||
%if &checktype = SASLibrary %then %do;
|
||||
%put WARNING: Library (&liburi) already exists with libref (&libref) ;
|
||||
%put %str(WARN)ING: Library (&liburi) already exists with libref (&libref) ;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7466,7 +7800,7 @@ data _null_;
|
||||
call symputx('treeuri',uri,'l');
|
||||
run;
|
||||
%if &foldertype ne Tree %then %do;
|
||||
%put WARNING: Tree &tree does not exist!;
|
||||
%put %str(WARN)ING: Tree &tree does not exist!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7574,7 +7908,7 @@ filename &frefout temp;
|
||||
* check SAS version
|
||||
*/
|
||||
%if %sysevalf(&sysver lt 9.3) %then %do;
|
||||
%put WARNING: Version 9.3 or later required;
|
||||
%put %str(WARN)ING: Version 9.3 or later required;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7782,7 +8116,7 @@ data _null_;
|
||||
call symputx('treeuri',uri,'l');
|
||||
run;
|
||||
%if &foldertype ne Tree %then %do;
|
||||
%put WARNING: Tree &tree does not exist!;
|
||||
%put %str(WARN)ING: Tree &tree does not exist!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7797,7 +8131,7 @@ data _null_;
|
||||
call symputx('stpuri',uri,'l');
|
||||
run;
|
||||
%if &cmtype = ClassifierMap %then %do;
|
||||
%put WARNING: Stored Process &stpname already exists in &tree!;
|
||||
%put %str(WARN)ING: Stored Process &stpname already exists in &tree!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7805,14 +8139,14 @@ run;
|
||||
* Check that the physical file exists
|
||||
*/
|
||||
%if %sysfunc(fileexist(&directory/&filename)) ne 1 %then %do;
|
||||
%put WARNING: FILE *&directory/&filename* NOT FOUND!;
|
||||
%put %str(WARN)ING: FILE *&directory/&filename* NOT FOUND!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%if &stptype=1 %then %do;
|
||||
/* type 1 STP - where code is stored on filesystem */
|
||||
%if %sysevalf(&sysver lt 9.2) %then %do;
|
||||
%put WARNING: Version 9.2 or later required;
|
||||
%put %str(WARN)ING: Version 9.2 or later required;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -7826,7 +8160,7 @@ run;
|
||||
%if &checkdirtype ne Directory %then %do;
|
||||
%mm_getdirectories(path=&directory,outds=&outds ,mDebug=&mDebug)
|
||||
%if %mf_nobs(&outds)=0 or %sysfunc(exist(&outds))=0 %then %do;
|
||||
%put WARNING: The directory object does not exist for &directory;
|
||||
%put %str(WARN)ING: The directory object does not exist for &directory;
|
||||
%return;
|
||||
%end;
|
||||
%end;
|
||||
@@ -7844,12 +8178,12 @@ run;
|
||||
length id $20 type $256;
|
||||
__rc=metadata_resolve("&treeuri",type,id);
|
||||
if type ne 'Tree' then do;
|
||||
putlog "WARNING: Invalid tree URI: &treeuri";
|
||||
putlog "%str(WARN)ING: Invalid tree URI: &treeuri";
|
||||
stopme=1;
|
||||
end;
|
||||
__rc=metadata_resolve(directoryuri,type,id);
|
||||
if type ne 'Directory' then do;
|
||||
putlog 'WARNING: Invalid directory URI: ' directoryuri;
|
||||
putlog "%str(WARN)ING: Invalid directory URI: " directoryuri;
|
||||
stopme=1;
|
||||
end;
|
||||
|
||||
@@ -7858,7 +8192,7 @@ run;
|
||||
if type ne 'LogicalServer' then do;
|
||||
__rc=metadata_getnobj("omsobj:LogicalServer?@Name='&server'",1,serveruri);
|
||||
if serveruri='' then do;
|
||||
putlog "WARNING: Invalid server: &server";
|
||||
putlog "%str(WARN)ING: Invalid server: &server";
|
||||
stopme=1;
|
||||
end;
|
||||
end;
|
||||
@@ -7881,7 +8215,7 @@ run;
|
||||
rc6 = METADATA_SETATTR(prompturi, 'GroupInfo',groupinfo);
|
||||
|
||||
if sum(of rc1-rc6) ne 0 then do;
|
||||
putlog 'WARNING: Issue creating prompt.';
|
||||
putlog "%str(WARN)ING: Issue creating prompt.";
|
||||
if prompturi ne . then do;
|
||||
putlog ' Removing orphan: ' prompturi;
|
||||
rc = METADATA_DELOBJ(prompturi);
|
||||
@@ -7896,7 +8230,7 @@ run;
|
||||
rc9=METADATA_SETATTR(fileuri, 'IsARelativeName','1');
|
||||
rc10=METADATA_SETASSN(fileuri, 'Directories','MODIFY',directoryuri);
|
||||
if sum(of rc7-rc10) ne 0 then do;
|
||||
putlog 'WARNING: Issue creating file.';
|
||||
putlog "%str(WARN)ING: Issue creating file.";
|
||||
if fileuri ne . then do;
|
||||
putlog ' Removing orphans:' prompturi fileuri;
|
||||
rc = METADATA_DELOBJ(prompturi);
|
||||
@@ -7915,7 +8249,7 @@ run;
|
||||
!!"<OutputParameters/></StoredProcess>";
|
||||
rc14= METADATA_SETATTR(texturi, 'StoredText',storedtext);
|
||||
if sum(of rc11-rc14) ne 0 then do;
|
||||
putlog 'WARNING: Issue creating TextStore.';
|
||||
putlog "%str(WARN)ING: Issue creating TextStore.";
|
||||
if texturi ne . then do;
|
||||
putlog ' Removing orphans: ' prompturi fileuri texturi;
|
||||
rc = METADATA_DELOBJ(prompturi);
|
||||
@@ -7963,7 +8297,7 @@ run;
|
||||
%else %if &stptype=2 %then %do;
|
||||
/* type 2 stp - code is stored in metadata */
|
||||
%if %sysevalf(&sysver lt 9.3) %then %do;
|
||||
%put WARNING: SAS version 9.3 or later required to create type2 STPs;
|
||||
%put %str(WARN)ING: SAS version 9.3 or later required to create type2 STPs;
|
||||
%return;
|
||||
%end;
|
||||
/* check we have the correct ServerContext */
|
||||
@@ -7975,7 +8309,7 @@ run;
|
||||
call symputx('serveruri',serveruri);
|
||||
run;
|
||||
%if &serveruri=NOTFOUND %then %do;
|
||||
%put WARNING: ServerContext *&server* not found!;
|
||||
%put %str(WARN)ING: ServerContext *&server* not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -8046,7 +8380,7 @@ run;
|
||||
|
||||
%end;
|
||||
%else %do;
|
||||
%put WARNING: STPTYPE=*&stptype* not recognised!;
|
||||
%put %str(WARN)ING: STPTYPE=*&stptype* not recognised!;
|
||||
%end;
|
||||
|
||||
%mend;/**
|
||||
@@ -8493,7 +8827,7 @@ data _null_;
|
||||
call symputx('stpuri',uri,'l');
|
||||
run;
|
||||
%if &type ne Document %then %do;
|
||||
%put WARNING: No Document found at ⌖
|
||||
%put %str(WARN)ING: No Document found at ⌖
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -9107,7 +9441,7 @@ data _null_;
|
||||
when ('
') rec='0D'x;
|
||||
when ('$' ) rec='$' ;
|
||||
when ('	') rec='09'x;
|
||||
otherwise putlog "WARNING: missing value for " entity=;
|
||||
otherwise putlog "%str(WARN)ING: missing value for " entity=;
|
||||
end;
|
||||
rc =fput(fileid, substr(rec,1,1));
|
||||
rc =fwrite(fileid);
|
||||
@@ -10907,7 +11241,7 @@ run;
|
||||
when ('
') rec='0D'x;
|
||||
when ('$' ) rec='$' ;
|
||||
when ('	') rec='09'x;
|
||||
otherwise putlog "WARNING: missing value for " entity=;
|
||||
otherwise putlog "%str(WARN)ING: missing value for " entity=;
|
||||
end;
|
||||
rc =fput(fileid, substr(rec,1,1));
|
||||
rc =fwrite(fileid);
|
||||
@@ -11306,7 +11640,7 @@ data _null_;
|
||||
run;
|
||||
|
||||
%if &appuri=stopifempty %then %do;
|
||||
%put WARNING: &app.(Application) not found!;
|
||||
%put %str(WARN)ING: &app.(Application) not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -11427,12 +11761,12 @@ data _null_;
|
||||
run;
|
||||
|
||||
%if &tsuri=stopifempty %then %do;
|
||||
%put WARNING: &path/&name.(Document) not found!;
|
||||
%put %str(WARN)ING: &path/&name.(Document) not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%if %length(&text)<2 %then %do;
|
||||
%put WARNING: No text supplied!!;
|
||||
%put %str(WARN)ING: No text supplied!!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -11518,7 +11852,7 @@ data _null_;
|
||||
call symputx('stpuri',uri,'l');
|
||||
run;
|
||||
%if &cmtype ne ClassifierMap %then %do;
|
||||
%put WARNING: No Stored Process found at ⌖
|
||||
%put %str(WARN)ING: No Stored Process found at ⌖
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -11619,12 +11953,12 @@ data _null_;
|
||||
run;
|
||||
|
||||
%if &tsuri=stopifempty %then %do;
|
||||
%put WARNING: &stp.(StoredProcess) not found!;
|
||||
%put %str(WARN)ING: &stp.(StoredProcess) not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%if %length(&stpcode)<2 %then %do;
|
||||
%put WARNING: No SAS code supplied!!;
|
||||
%put %str(WARN)ING: No SAS code supplied!!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
@file
|
||||
@brief Checks if a set of variables ALL exist in a data set.
|
||||
@details Returns 0 if ANY of the variables do not exist, or 1 if they ALL do.
|
||||
Usage:
|
||||
Usage:
|
||||
|
||||
%put %mf_existVarList(sashelp.class, age sex name dummyvar)
|
||||
%put %mf_existVarList(sashelp.class, age sex name dummyvar);
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_abort.sas
|
||||
@@ -29,7 +29,7 @@
|
||||
%let dsid=%sysfunc(open(&libds,is));
|
||||
|
||||
%if &dsid=0 %then %do;
|
||||
%put WARNING: unable to open &libds in mf_existvarlist (&dsid);
|
||||
%put %str(WARN)ING: unable to open &libds in mf_existvarlist (&dsid);
|
||||
%end;
|
||||
|
||||
%if %sysfunc(attrn(&dsid,NVARS))=0 %then %do;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
%local dsid rc;
|
||||
%let dsid=%sysfunc(open(&libds,is));
|
||||
%if &dsid = 0 %then %do;
|
||||
%put WARNING: Cannot open %trim(&libds), system message below;
|
||||
%put %str(WARN)ING: Cannot open %trim(&libds), system message below;
|
||||
%put %sysfunc(sysmsg());
|
||||
-1
|
||||
%end;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
%local count_base count_extr i i2 extr_word base_word match outvar;
|
||||
%if %length(&str1)=0 or %length(&str2)=0 %then %do;
|
||||
%put WARNING: empty string provided!;
|
||||
%put %str(WARN)ING: empty string provided!;
|
||||
%put base string (str1)= &str1;
|
||||
%put compare string (str2) = &str2;
|
||||
%return;
|
||||
|
||||
145
base/mp_assertcols.sas
Normal file
145
base/mp_assertcols.sas
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
@file
|
||||
@brief Asserts the existence (or not) of columns
|
||||
@details Useful in the context of writing sasjs tests. The results of the
|
||||
test are _appended_ to the &outds. table.
|
||||
|
||||
Example usage:
|
||||
|
||||
%mp_assertcols(sashelp.class,
|
||||
cols=name age sex,
|
||||
test=ALL,
|
||||
desc=check all columns exist
|
||||
)
|
||||
|
||||
%mp_assertcols(sashelp.class,
|
||||
cols=a b c,
|
||||
test=NONE
|
||||
)
|
||||
|
||||
%mp_assertcols(sashelp.class,
|
||||
cols=age depth,
|
||||
test=ANY
|
||||
)
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_existds.sas
|
||||
@li mf_existvarlist.sas
|
||||
@li mf_getvarlist.sas
|
||||
@li mf_wordsinstr1butnotstr2.sas
|
||||
@li mp_abort.sas
|
||||
|
||||
|
||||
@param [in] inds The input library.dataset to test for values
|
||||
@param [in] cols= The list of columns to check for
|
||||
@param [in] desc= (Testing observations) The user provided test description
|
||||
@param [in] test= (ALL) The test to apply. Valid values are:
|
||||
@li ALL - Test is a PASS if ALL columns exist in &inds
|
||||
@li ANY - Test is a PASS if ANY of the columns exist in &inds
|
||||
@li NONE - Test is a PASS if NONE of the columns exist in &inds
|
||||
@param [out] outds= (work.test_results) The output dataset to contain the
|
||||
results. If it does not exist, it will be created, with the following format:
|
||||
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
||||
|---|---|---|
|
||||
|User Provided description|PASS|Column &inds contained ALL columns|
|
||||
|
||||
|
||||
<h4> Related Macros </h4>
|
||||
@li mp_assertdsobs.sas
|
||||
@li mp_assertcolvals.sas
|
||||
@li mp_assertdsobs.sas
|
||||
|
||||
@version 9.2
|
||||
@author Allan Bowe
|
||||
|
||||
**/
|
||||
|
||||
%macro mp_assertcols(inds,
|
||||
cols=0,
|
||||
test=ALL,
|
||||
desc=0,
|
||||
outds=work.test_results
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%mp_abort(iftrue= (&syscc ne 0)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(syscc=&syscc - on macro entry)
|
||||
)
|
||||
|
||||
%local lib ds ;
|
||||
%let lib=%scan(&inds,1,%str(.));
|
||||
%let ds=%scan(&inds,2,%str(.));
|
||||
%let cols=%upcase(&cols);
|
||||
|
||||
%mp_abort(iftrue= (%mf_existds(&lib..&ds)=0)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(&lib..&ds not found!)
|
||||
)
|
||||
|
||||
%mp_abort(iftrue= (&cols=0)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(No cols provided)
|
||||
)
|
||||
|
||||
|
||||
%let test=%upcase(&test);
|
||||
|
||||
%if &test ne ANY and &test ne ALL and &test ne NONE %then %do;
|
||||
%mp_abort(
|
||||
mac=&sysmacroname,
|
||||
msg=%str(Invalid test - &test)
|
||||
)
|
||||
%end;
|
||||
|
||||
/**
|
||||
* now do the actual test!
|
||||
*/
|
||||
%local result;
|
||||
%if %mf_existVarList(&inds,&cols)=1 %then %let result=ALL;
|
||||
%else %do;
|
||||
%local targetcols compare;
|
||||
%let targetcols=%upcase(%mf_getvarlist(&inds));
|
||||
%let compare=%mf_wordsinstr1butnotstr2(
|
||||
Str1=&cols,
|
||||
Str2=&targetcols
|
||||
);
|
||||
%if %cmpres(&compare)=%cmpres(&cols) %then %let result=NONE;
|
||||
%else %let result=SOME;
|
||||
%end;
|
||||
|
||||
data;
|
||||
length test_description $256 test_result $4 test_comments $256;
|
||||
test_description=symget('desc');
|
||||
if test_description='0'
|
||||
then test_description="Testing &inds for existence of &test of: &cols";
|
||||
|
||||
test_result='FAIL';
|
||||
test_comments="&sysmacroname: &inds has &result columns ";
|
||||
%if &test=ALL %then %do;
|
||||
%if &result=ALL %then %do;
|
||||
test_result='PASS';
|
||||
%end;
|
||||
%end;
|
||||
%else %if &test=ANY %then %do;
|
||||
%if &result=SOME %then %do;
|
||||
test_result='PASS';
|
||||
%end;
|
||||
%end;
|
||||
%else %if &test=NONE %then %do;
|
||||
%if &result=NONE %then %do;
|
||||
test_result='PASS';
|
||||
%end;
|
||||
%end;
|
||||
%else %do;
|
||||
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
||||
%end;
|
||||
run;
|
||||
|
||||
%local ds;
|
||||
%let ds=&syslast;
|
||||
proc append base=&outds data=&ds;
|
||||
run;
|
||||
proc sql;
|
||||
drop table &ds;
|
||||
|
||||
%mend;
|
||||
@@ -43,7 +43,7 @@
|
||||
%local i setds nvars;
|
||||
|
||||
%if not %sysfunc(exist(&base_ds)) %then %do;
|
||||
%put WARNING: &base_ds does not exist;
|
||||
%put %str(WARN)ING: &base_ds does not exist;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -61,7 +61,7 @@ select count(*) into: nvars from dictionary.columns
|
||||
where libname="%scan(%upcase(&base_ds),1)"
|
||||
and memname="%scan(%upcase(&base_ds),2)";
|
||||
%if &nvars=0 %then %do;
|
||||
%put WARNING: Dataset &base_ds has no variables! It will not be converted.;
|
||||
%put %str(WARN)ING: Dataset &base_ds has no variables, will not be converted.;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%if not %sysfunc(exist(&ds)) %then %do;
|
||||
%put WARNING: &ds does not exist;
|
||||
%put %str(WARN)ING: &ds does not exist;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -141,18 +141,18 @@ data &outds;
|
||||
|
||||
run;
|
||||
|
||||
data _null_;
|
||||
set &outds;
|
||||
call symputx('REASON_CD',reason_cd,'l');
|
||||
stop;
|
||||
run;
|
||||
|
||||
%mp_abort(iftrue=(&abort=YES),
|
||||
mac=&sysmacroname,
|
||||
msg=%str(Filter issues in &inds, first was &reason_cd, details in &outds)
|
||||
)
|
||||
|
||||
%if %mf_nobs(&outds)>0 %then %do;
|
||||
%if &abort=YES %then %do;
|
||||
data _null_;
|
||||
set &outds;
|
||||
call symputx('REASON_CD',reason_cd,'l');
|
||||
stop;
|
||||
run;
|
||||
%mp_abort(
|
||||
mac=&sysmacroname,
|
||||
msg=%str(Filter issues in &inds, first was &reason_cd, details in &outds)
|
||||
)
|
||||
%end;
|
||||
%let syscc=1008;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -88,13 +88,14 @@ filename &outref temp;
|
||||
file &outref lrecl=32800;
|
||||
set &inds end=last;
|
||||
by SUBGROUP_ID;
|
||||
if _n_=1 then put '(';
|
||||
if _n_=1 then put '((';
|
||||
else if first.SUBGROUP_ID then put +1 GROUP_LOGIC '(';
|
||||
else put +2 SUBGROUP_LOGIC;
|
||||
|
||||
put +4 VARIABLE_NM OPERATOR_NM RAW_VALUE;
|
||||
|
||||
if last.SUBGROUP_ID then put ')'@;
|
||||
if last then put ')';
|
||||
run;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -36,8 +36,20 @@
|
||||
%let contentype=%upcase(&contenttype);
|
||||
%local platform; %let platform=%mf_getplatform();
|
||||
|
||||
|
||||
/**
|
||||
* check engine type to avoid the below err message:
|
||||
* > Function is only valid for filerefs using the CACHE access method.
|
||||
*/
|
||||
%local streamweb;
|
||||
%let streamweb=0;
|
||||
data _null_;
|
||||
set sashelp.vextfl(where=(upcase(fileref)="_WEBOUT"));
|
||||
if xengine='STREAM' then call symputx('streamweb',1,'l');
|
||||
run;
|
||||
|
||||
%if &contentype=ZIP %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/zip');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -51,7 +63,7 @@
|
||||
%end;
|
||||
%else %if &contentype=EXCEL %then %do;
|
||||
/* suitable for XLS format */
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/vnd.ms-excel');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -64,7 +76,7 @@
|
||||
%end;
|
||||
%end;
|
||||
%else %if &contentype=XLSX %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
@@ -79,7 +91,7 @@
|
||||
%end;
|
||||
%end;
|
||||
%else %if &contentype=TEXT %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/text');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -92,7 +104,7 @@
|
||||
%end;
|
||||
%end;
|
||||
%else %if &contentype=CSV %then %do;
|
||||
%if &platform=SASMETA %then %do;
|
||||
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||
data _null_;
|
||||
rc=stpsrv_header('Content-type','application/csv');
|
||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||
@@ -122,4 +134,4 @@
|
||||
%mp_binarycopy(inloc="&inloc",outref=_webout)
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
%mend;
|
||||
|
||||
65
base/mp_validatecol.sas
Normal file
65
base/mp_validatecol.sas
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
@file
|
||||
@brief Used to validate variables in a dataset
|
||||
@details Useful when sanitising inputs, to ensure that they arrive with a
|
||||
certain pattern.
|
||||
Usage:
|
||||
|
||||
data test;
|
||||
infile datalines4 dsd;
|
||||
input;
|
||||
libds=_infile_;
|
||||
%mp_validatecol(libds,LIBDS,is_libds)
|
||||
datalines4;
|
||||
some.libname
|
||||
!lib.blah
|
||||
%abort
|
||||
definite.ok
|
||||
not.ok!
|
||||
nineletrs._
|
||||
;;;;
|
||||
run;
|
||||
|
||||
@param [in] incol The column to be validated
|
||||
@param [in] rule The rule to apply. Current rules:
|
||||
@li LIBDS - matches LIBREF.DATASET format
|
||||
@param [out] outcol The variable to create, with the results of the match
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquename.sas
|
||||
|
||||
@version 9.3
|
||||
**/
|
||||
|
||||
%macro mp_validatecol(incol,rule,outcol);
|
||||
|
||||
/* tempcol is given a unique name with every invocation */
|
||||
%local tempcol;
|
||||
%let tempcol=%mf_getuniquename();
|
||||
|
||||
%if &rule=ISNUM %then %do;
|
||||
/*
|
||||
credit SØREN LASSEN
|
||||
https://sasmacro.blogspot.com/2009/06/welcome-isnum-macro.html
|
||||
*/
|
||||
&tempcol=input(&incol,?? best32.);
|
||||
if missing(&tempcol) then &outcol=0;
|
||||
else &outcol=1;
|
||||
drop &tempcol;
|
||||
%end;
|
||||
%else %if &rule=LIBDS %then %do;
|
||||
/* match libref.dataset */
|
||||
if _n_=1 then do;
|
||||
retain &tempcol;
|
||||
&tempcol=prxparse('/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i');
|
||||
if missing(&tempcol) then do;
|
||||
putlog "%str(ERR)OR: Invalid expression for LIBDS";
|
||||
stop;
|
||||
end;
|
||||
drop &tempcol;
|
||||
end;
|
||||
if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
|
||||
else &outcol=0;
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
@@ -2,11 +2,11 @@
|
||||
@file
|
||||
@brief Creates a zip file
|
||||
@details For DIRECTORY usage, will ignore subfolders. For DATASET usage,
|
||||
provide a column that contains the full file path to each file to be zipped.
|
||||
provide a column that contains the full file path to each file to be zipped.
|
||||
|
||||
%mp_zip(in=myzips,type=directory,outname=myDir)
|
||||
%mp_zip(in=/my/file/path.txt,type=FILE,outname=myFile)
|
||||
%mp_zip(in=SOMEDS,incol=FPATH,type=DATASET,outname=myFile)
|
||||
%mp_zip(in=myzips,type=directory,outname=myDir)
|
||||
%mp_zip(in=/my/file/path.txt,type=FILE,outname=myFile)
|
||||
%mp_zip(in=SOMEDS,incol=FPATH,type=DATASET,outname=myFile)
|
||||
|
||||
If you are sending zipped output to the _webout destination as part of an STP
|
||||
be sure that _debug is not set (else the SPWA will send non zipped content
|
||||
|
||||
@@ -70,7 +70,7 @@ run;
|
||||
%end;
|
||||
|
||||
%if &syscc ge 4 %then %do;
|
||||
%put WARNING: SYSCC=&syscc, exiting &sysmacroname;
|
||||
%put %str(WARN)ING: SYSCC=&syscc, exiting &sysmacroname;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ run;
|
||||
run;
|
||||
|
||||
%if %length(&open_passthrough)>0 %then %do;
|
||||
%put WARNING: Passthrough option for postgres not yet supported;
|
||||
%put %str(WARN)ING: Passthrough option for postgres not yet supported;
|
||||
%return;
|
||||
%end;
|
||||
%else %do;
|
||||
@@ -455,8 +455,8 @@ run;
|
||||
%return;
|
||||
%end;
|
||||
%else %do;
|
||||
%put WARNING: Engine &engine is currently unsupported;
|
||||
%put WARNING- Please contact your support team.;
|
||||
%put %str(WARN)ING: Engine &engine is currently unsupported;
|
||||
%put %str(WARN)ING- Please contact your support team.;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ data _null_;
|
||||
putlog (_all_)(=);
|
||||
run;
|
||||
%if &checktype = SASLibrary %then %do;
|
||||
%put WARNING: Library (&liburi) already exists with libname (&libname) ;
|
||||
%put %str(WARN)ING: Library (&liburi) already exists with libname (&libname);
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -103,7 +103,7 @@ data _null_;
|
||||
putlog (_all_)(=);
|
||||
run;
|
||||
%if &checktype = SASLibrary %then %do;
|
||||
%put WARNING: Library (&liburi) already exists with libref (&libref) ;
|
||||
%put %str(WARN)ING: Library (&liburi) already exists with libref (&libref) ;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -123,7 +123,7 @@ data _null_;
|
||||
call symputx('treeuri',uri,'l');
|
||||
run;
|
||||
%if &foldertype ne Tree %then %do;
|
||||
%put WARNING: Tree &tree does not exist!;
|
||||
%put %str(WARN)ING: Tree &tree does not exist!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -231,7 +231,7 @@ filename &frefout temp;
|
||||
* check SAS version
|
||||
*/
|
||||
%if %sysevalf(&sysver lt 9.3) %then %do;
|
||||
%put WARNING: Version 9.3 or later required;
|
||||
%put %str(WARN)ING: Version 9.3 or later required;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ data _null_;
|
||||
call symputx('treeuri',uri,'l');
|
||||
run;
|
||||
%if &foldertype ne Tree %then %do;
|
||||
%put WARNING: Tree &tree does not exist!;
|
||||
%put %str(WARN)ING: Tree &tree does not exist!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -133,7 +133,7 @@ data _null_;
|
||||
call symputx('stpuri',uri,'l');
|
||||
run;
|
||||
%if &cmtype = ClassifierMap %then %do;
|
||||
%put WARNING: Stored Process &stpname already exists in &tree!;
|
||||
%put %str(WARN)ING: Stored Process &stpname already exists in &tree!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -141,14 +141,14 @@ run;
|
||||
* Check that the physical file exists
|
||||
*/
|
||||
%if %sysfunc(fileexist(&directory/&filename)) ne 1 %then %do;
|
||||
%put WARNING: FILE *&directory/&filename* NOT FOUND!;
|
||||
%put %str(WARN)ING: FILE *&directory/&filename* NOT FOUND!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%if &stptype=1 %then %do;
|
||||
/* type 1 STP - where code is stored on filesystem */
|
||||
%if %sysevalf(&sysver lt 9.2) %then %do;
|
||||
%put WARNING: Version 9.2 or later required;
|
||||
%put %str(WARN)ING: Version 9.2 or later required;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -162,7 +162,7 @@ run;
|
||||
%if &checkdirtype ne Directory %then %do;
|
||||
%mm_getdirectories(path=&directory,outds=&outds ,mDebug=&mDebug)
|
||||
%if %mf_nobs(&outds)=0 or %sysfunc(exist(&outds))=0 %then %do;
|
||||
%put WARNING: The directory object does not exist for &directory;
|
||||
%put %str(WARN)ING: The directory object does not exist for &directory;
|
||||
%return;
|
||||
%end;
|
||||
%end;
|
||||
@@ -180,12 +180,12 @@ run;
|
||||
length id $20 type $256;
|
||||
__rc=metadata_resolve("&treeuri",type,id);
|
||||
if type ne 'Tree' then do;
|
||||
putlog "WARNING: Invalid tree URI: &treeuri";
|
||||
putlog "%str(WARN)ING: Invalid tree URI: &treeuri";
|
||||
stopme=1;
|
||||
end;
|
||||
__rc=metadata_resolve(directoryuri,type,id);
|
||||
if type ne 'Directory' then do;
|
||||
putlog 'WARNING: Invalid directory URI: ' directoryuri;
|
||||
putlog "%str(WARN)ING: Invalid directory URI: " directoryuri;
|
||||
stopme=1;
|
||||
end;
|
||||
|
||||
@@ -194,7 +194,7 @@ run;
|
||||
if type ne 'LogicalServer' then do;
|
||||
__rc=metadata_getnobj("omsobj:LogicalServer?@Name='&server'",1,serveruri);
|
||||
if serveruri='' then do;
|
||||
putlog "WARNING: Invalid server: &server";
|
||||
putlog "%str(WARN)ING: Invalid server: &server";
|
||||
stopme=1;
|
||||
end;
|
||||
end;
|
||||
@@ -217,7 +217,7 @@ run;
|
||||
rc6 = METADATA_SETATTR(prompturi, 'GroupInfo',groupinfo);
|
||||
|
||||
if sum(of rc1-rc6) ne 0 then do;
|
||||
putlog 'WARNING: Issue creating prompt.';
|
||||
putlog "%str(WARN)ING: Issue creating prompt.";
|
||||
if prompturi ne . then do;
|
||||
putlog ' Removing orphan: ' prompturi;
|
||||
rc = METADATA_DELOBJ(prompturi);
|
||||
@@ -232,7 +232,7 @@ run;
|
||||
rc9=METADATA_SETATTR(fileuri, 'IsARelativeName','1');
|
||||
rc10=METADATA_SETASSN(fileuri, 'Directories','MODIFY',directoryuri);
|
||||
if sum(of rc7-rc10) ne 0 then do;
|
||||
putlog 'WARNING: Issue creating file.';
|
||||
putlog "%str(WARN)ING: Issue creating file.";
|
||||
if fileuri ne . then do;
|
||||
putlog ' Removing orphans:' prompturi fileuri;
|
||||
rc = METADATA_DELOBJ(prompturi);
|
||||
@@ -251,7 +251,7 @@ run;
|
||||
!!"<OutputParameters/></StoredProcess>";
|
||||
rc14= METADATA_SETATTR(texturi, 'StoredText',storedtext);
|
||||
if sum(of rc11-rc14) ne 0 then do;
|
||||
putlog 'WARNING: Issue creating TextStore.';
|
||||
putlog "%str(WARN)ING: Issue creating TextStore.";
|
||||
if texturi ne . then do;
|
||||
putlog ' Removing orphans: ' prompturi fileuri texturi;
|
||||
rc = METADATA_DELOBJ(prompturi);
|
||||
@@ -299,7 +299,7 @@ run;
|
||||
%else %if &stptype=2 %then %do;
|
||||
/* type 2 stp - code is stored in metadata */
|
||||
%if %sysevalf(&sysver lt 9.3) %then %do;
|
||||
%put WARNING: SAS version 9.3 or later required to create type2 STPs;
|
||||
%put %str(WARN)ING: SAS version 9.3 or later required to create type2 STPs;
|
||||
%return;
|
||||
%end;
|
||||
/* check we have the correct ServerContext */
|
||||
@@ -311,7 +311,7 @@ run;
|
||||
call symputx('serveruri',serveruri);
|
||||
run;
|
||||
%if &serveruri=NOTFOUND %then %do;
|
||||
%put WARNING: ServerContext *&server* not found!;
|
||||
%put %str(WARN)ING: ServerContext *&server* not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -382,7 +382,7 @@ run;
|
||||
|
||||
%end;
|
||||
%else %do;
|
||||
%put WARNING: STPTYPE=*&stptype* not recognised!;
|
||||
%put %str(WARN)ING: STPTYPE=*&stptype* not recognised!;
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
@@ -32,7 +32,7 @@ data _null_;
|
||||
call symputx('stpuri',uri,'l');
|
||||
run;
|
||||
%if &type ne Document %then %do;
|
||||
%put WARNING: No Document found at ⌖
|
||||
%put %str(WARN)ING: No Document found at ⌖
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ data _null_;
|
||||
when ('
') rec='0D'x;
|
||||
when ('$' ) rec='$' ;
|
||||
when ('	') rec='09'x;
|
||||
otherwise putlog "WARNING: missing value for " entity=;
|
||||
otherwise putlog "%str(WARN)ING: missing value for " entity=;
|
||||
end;
|
||||
rc =fput(fileid, substr(rec,1,1));
|
||||
rc =fwrite(fileid);
|
||||
|
||||
@@ -99,7 +99,7 @@ run;
|
||||
when ('
') rec='0D'x;
|
||||
when ('$' ) rec='$' ;
|
||||
when ('	') rec='09'x;
|
||||
otherwise putlog "WARNING: missing value for " entity=;
|
||||
otherwise putlog "%str(WARN)ING: missing value for " entity=;
|
||||
end;
|
||||
rc =fput(fileid, substr(rec,1,1));
|
||||
rc =fwrite(fileid);
|
||||
|
||||
@@ -70,7 +70,7 @@ data _null_;
|
||||
run;
|
||||
|
||||
%if &appuri=stopifempty %then %do;
|
||||
%put WARNING: &app.(Application) not found!;
|
||||
%put %str(WARN)ING: &app.(Application) not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -58,12 +58,12 @@ data _null_;
|
||||
run;
|
||||
|
||||
%if &tsuri=stopifempty %then %do;
|
||||
%put WARNING: &path/&name.(Document) not found!;
|
||||
%put %str(WARN)ING: &path/&name.(Document) not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%if %length(&text)<2 %then %do;
|
||||
%put WARNING: No text supplied!!;
|
||||
%put %str(WARN)ING: No text supplied!!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ data _null_;
|
||||
call symputx('stpuri',uri,'l');
|
||||
run;
|
||||
%if &cmtype ne ClassifierMap %then %do;
|
||||
%put WARNING: No Stored Process found at ⌖
|
||||
%put %str(WARN)ING: No Stored Process found at ⌖
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -68,12 +68,12 @@ data _null_;
|
||||
run;
|
||||
|
||||
%if &tsuri=stopifempty %then %do;
|
||||
%put WARNING: &stp.(StoredProcess) not found!;
|
||||
%put %str(WARN)ING: &stp.(StoredProcess) not found!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%if %length(&stpcode)<2 %then %do;
|
||||
%put WARNING: No SAS code supplied!!;
|
||||
%put %str(WARN)ING: No SAS code supplied!!;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
|
||||
@@ -17,7 +17,22 @@
|
||||
}
|
||||
},
|
||||
"serviceConfig": {
|
||||
"initProgram": "tests/testinit.sas"
|
||||
"initProgram": "tests/testinit.sas",
|
||||
"termProgram": "tests/testterm.sas",
|
||||
"serviceFolders": [
|
||||
"tests/base",
|
||||
"tests/viya"
|
||||
],
|
||||
"macroVars": {
|
||||
"mcTestAppLoc": "/Public/temp/macrocore"
|
||||
}
|
||||
},
|
||||
"testConfig": {
|
||||
"initProgram": "tests/testinit.sas",
|
||||
"termProgram": "tests/testterm.sas",
|
||||
"macroVars": {
|
||||
"mcTestAppLoc": "/Public/temp/macrocore"
|
||||
}
|
||||
},
|
||||
"defaultTarget": "viya",
|
||||
"targets": [
|
||||
@@ -26,15 +41,6 @@
|
||||
"serverUrl": "https://sas.analytium.co.uk",
|
||||
"serverType": "SASVIYA",
|
||||
"appLoc": "/Public/temp/macrocore",
|
||||
"serviceConfig": {
|
||||
"serviceFolders": [
|
||||
"tests/base",
|
||||
"tests/viya"
|
||||
],
|
||||
"macroVars": {
|
||||
"mcTestAppLoc": "/Public/temp/macrocore"
|
||||
}
|
||||
},
|
||||
"deployConfig": {
|
||||
"deployServicePack": true
|
||||
},
|
||||
|
||||
@@ -30,7 +30,3 @@ run;
|
||||
test=ALLVALS
|
||||
)
|
||||
|
||||
|
||||
%webout(OPEN)
|
||||
%webout(OBJ, TEST_RESULTS)
|
||||
%webout(CLOSE)
|
||||
@@ -125,8 +125,3 @@ run;
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
|
||||
|
||||
%webout(OPEN)
|
||||
%webout(OBJ, TEST_RESULTS)
|
||||
%webout(CLOSE)
|
||||
@@ -120,7 +120,3 @@ run;
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
|
||||
%webout(OPEN)
|
||||
%webout(OBJ, TEST_RESULTS)
|
||||
%webout(CLOSE)
|
||||
@@ -66,7 +66,3 @@ run;
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
|
||||
%webout(OPEN)
|
||||
%webout(OBJ, TEST_RESULTS)
|
||||
%webout(CLOSE)
|
||||
62
tests/base/mp_validatecol.test.sas
Normal file
62
tests/base/mp_validatecol.test.sas
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mp_validatecol.sas macro
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mp_assertdsobs.sas
|
||||
@li mp_validatecol.sas
|
||||
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Test 1 - LIBDS
|
||||
*/
|
||||
data test1;
|
||||
infile datalines4 dsd;
|
||||
input;
|
||||
libds=_infile_;
|
||||
%mp_validatecol(libds,LIBDS,is_libds)
|
||||
if libds=1;
|
||||
datalines4;
|
||||
some.libname
|
||||
!lib.blah
|
||||
%abort
|
||||
definite.ok
|
||||
not.ok!
|
||||
nineletrs._
|
||||
;;;;
|
||||
run;
|
||||
%mp_assertdsobs(work.test1,
|
||||
desc=Testing LIBDS,
|
||||
test=EQUALS 2,
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
/**
|
||||
* Test 2 - ISNUM
|
||||
*/
|
||||
data test2;
|
||||
infile datalines4 dsd;
|
||||
input;
|
||||
infile=_infile_;
|
||||
%mp_validatecol(infile,ISNUM,is_numeric)
|
||||
if is_numeric=1;
|
||||
datalines4;
|
||||
1
|
||||
0001
|
||||
1e6
|
||||
-44
|
||||
above are good
|
||||
the rest are bad
|
||||
%abort
|
||||
1&somethingverybad.
|
||||
&
|
||||
+-1
|
||||
;;;;
|
||||
run;
|
||||
%mp_assertdsobs(work.test2,
|
||||
desc=Test2 - ISNUM,
|
||||
test=EQUALS 4,
|
||||
outds=work.test_results
|
||||
)
|
||||
9
tests/testterm.sas
Normal file
9
tests/testterm.sas
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
@file
|
||||
@brief term file for tests
|
||||
|
||||
**/
|
||||
|
||||
%webout(OPEN)
|
||||
%webout(OBJ, TEST_RESULTS)
|
||||
%webout(CLOSE)
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mv_createwebservice.sas
|
||||
@li mv_getjobcode.sas
|
||||
|
||||
**/
|
||||
|
||||
@@ -21,4 +22,20 @@ run;
|
||||
path=&mcTestAppLoc/tests/macros,
|
||||
code=testref,
|
||||
name=mv_createwebservice
|
||||
)
|
||||
)
|
||||
|
||||
filename compare temp;
|
||||
%mv_getjobcode(
|
||||
path=&mcTestAppLoc/tests/macros
|
||||
,name=mv_createwebservice
|
||||
,outref=compare;
|
||||
)
|
||||
|
||||
data test_results;
|
||||
length test_description $256 test_result $4 test_comments $256;
|
||||
infile compare;
|
||||
input;
|
||||
if _infile_='01'x then test_result='PASS';
|
||||
else test_result='FAIL';
|
||||
test_description="Creating web service with invisible character";
|
||||
run;
|
||||
Reference in New Issue
Block a user