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

Compare commits

...

10 Commits

Author SHA1 Message Date
munja
d49b21f3f1 fix: initialising name/uri in mv_jobexecute 2021-12-14 08:42:39 +00:00
munja
a45d280a51 fix: avoiding uninitialised variables in mv_getjobcode and mv_getfoldermembers 2021-12-14 08:20:32 +00:00
Allan Bowe
2536e299ad Merge pull request #112 from sasjs/mf_isint
feat: new macro to determine if a macro variable value is an integer …
2021-12-13 18:55:41 +00:00
munja
8b5238230b feat: new macro to determine if a macro variable value is an integer - mf_isint (and associated test) 2021-12-13 18:36:22 +00:00
munja
0ce7efee3e fix: declaring msg variable prior to set statement in mp_copyfolder.sas 2021-12-13 11:26:17 +00:00
munja
357677e45c chore: switching pre-commit hook to bash from shell 2021-12-13 09:14:29 +00:00
Allan Bowe
a4a332926e Merge pull request #111 from sasjs/issue110
feat: adding varinitchk=ERROR to mp_init.  Closes #110.
2021-12-13 08:44:12 +00:00
munja
0a29006914 chore: running all.sas 2021-12-13 01:08:37 +00:00
munja
0885bad859 fix: updating the tests following varinitchk=error enablement. Removing the word 'error' from documenttion. 2021-12-13 01:07:54 +00:00
munja
42bd1750bd feat: adding varinitchk=ERROR to mp_init. Closes #110. Also updated the comments / documentation 2021-12-12 22:57:25 +00:00
26 changed files with 225 additions and 66 deletions

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
sasjs lint sasjs lint
# Avoid commits to the master branch # Avoid commits to the master branch

125
all.sas
View File

@@ -79,7 +79,7 @@ options noquotelenmax;
Run without arguments to see a list of detectable features. Run without arguments to see a list of detectable features.
Note - this list is based on known versions of SAS rather than Note - this list is based on known versions of SAS rather than
actual feature detection, as that is tricky / impossible to do actual feature detection, as that is tricky / impossible to do
without generating errors in most cases. without generating errs in most cases.
%put %mf_existfeature(PROCLUA); %put %mf_existfeature(PROCLUA);
@@ -362,7 +362,7 @@ https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md#functionex
@param attr full list in [documentation]( @param attr full list in [documentation](
https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000147794.htm) https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000147794.htm)
@return output returns result of the attrc value supplied, or -1 and log @return output returns result of the attrc value supplied, or -1 and log
message if error. message if err.
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@@ -395,7 +395,7 @@ https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md#functionex
@param attr Common values are NLOBS and NVARS, full list in [documentation]( @param attr Common values are NLOBS and NVARS, full list in [documentation](
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212040.htm) http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212040.htm)
@return output returns result of the attrn value supplied, or -1 and log @return output returns result of the attrn value supplied, or -1 and log
message if error. message if err.
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@@ -1340,6 +1340,38 @@ Usage:
&is_directory &is_directory
%mend mf_isdir;/** %mend mf_isdir;/**
@file
@brief Returns 1 if the variable contains only digits 0-9, else 0
@details Note that numerics containing any punctuation (including decimals
or exponents) will be flagged zero.
If you'd like support for this, then do raise an issue (or even better, a
pull request!)
Usage:
%put %mf_isint(1) returns 1;
%put %mf_isint(1.1) returns 0;
%put %mf_isint(%str(1,1)) returns 0;
@param [in] arg input value to check
@version 9.2
**/
%macro mf_isint(arg
)/*/STORE SOURCE*/;
/* remove minus sign if exists */
%local val;
%if "%substr(%str(&arg),1,1)"="-" %then %let val=%substr(%str(&arg),2);
%else %let val=&arg;
/* check remaining chars */
%if %sysfunc(findc(%str(&val),,kd)) %then %do;0%end;
%else %do;1%end;
%mend mf_isint;/**
@file @file
@brief Returns physical location of various SAS items @brief Returns physical location of various SAS items
@details Returns location of the PlatformObjectFramework tools @details Returns location of the PlatformObjectFramework tools
@@ -1421,7 +1453,7 @@ Usage:
%end; %end;
/* /*
Now create the directory. Complain loudly of any errors. Now create the directory. Complain loudly of any errs.
*/ */
%let dname = %sysfunc(dcreate(&child, &parent)); %let dname = %sysfunc(dcreate(&child, &parent));
@@ -1468,7 +1500,7 @@ Usage:
@param libds library.dataset @param libds library.dataset
@return output returns result of the attrn value supplied, or log message @return output returns result of the attrn value supplied, or log message
if error. if err.
@version 9.2 @version 9.2
@@ -2790,6 +2822,8 @@ run;
/* create folders and copy content */ /* create folders and copy content */
data _null_; data _null_;
length msg $200;
call missing(msg);
set work.&tempds; set work.&tempds;
if _n_ = 1 then dpos+sum(length(directory),2); if _n_ = 1 then dpos+sum(length(directory),2);
filepath2="&target/"!!substr(filepath,dpos); filepath2="&target/"!!substr(filepath,dpos);
@@ -2799,9 +2833,9 @@ run;
rc1=filename(fref1,filepath,'disk','recfm=n'); rc1=filename(fref1,filepath,'disk','recfm=n');
rc2=filename(fref2,filepath2,'disk','recfm=n'); rc2=filename(fref2,filepath2,'disk','recfm=n');
if fcopy(fref1,fref2) ne 0 then do; if fcopy(fref1,fref2) ne 0 then do;
sysmsg=sysmsg(); msg=sysmsg();
putlog "%str(ERR)OR: Unable to copy " filepath " to " filepath2; putlog "%str(ERR)OR: Unable to copy " filepath " to " filepath2;
putlog sysmg=; putlog msg=;
end; end;
end; end;
rc=filename(fref1); rc=filename(fref1);
@@ -3876,17 +3910,23 @@ run;
%mend mp_ds2csv;/** %mend mp_ds2csv;/**
@file @file
@brief Converts every value in a dataset to it's formatted value @brief Converts every value in a dataset to formatted value
@details Converts every value to it's formatted value. All variables will @details Converts every value to it's formatted value. All variables will
become character, and will be in the same order. become character, and will be in the same order as the original dataset.
Lengths will be adjusted according to the format lengths, where applicable.
Usage: Usage:
%mp_ds2fmtds(sashelp.cars,work.cars) %mp_ds2fmtds(sashelp.cars,work.cars)
%mp_ds2fmtds(sashelp.vallopt,vw_vallopt)
@param [in] libds The library.dataset to be converted @param [in] libds The library.dataset to be converted
@param [out] outds The dataset to create. @param [out] outds The dataset to create.
<h4> SAS Macros </h4>
@li mf_existds.sas
<h4> Related Macros <h4> <h4> Related Macros <h4>
@li mp_jsonout.sas @li mp_jsonout.sas
@@ -3898,8 +3938,9 @@ run;
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
/* validations */ /* validations */
%if not %sysfunc(exist(&libds)) %then %do;
%put %str(WARN)ING: &libds does not exist; %if not %mf_existds(libds=&libds) %then %do;
%put %str(WARN)ING: &libds does not exist as either a VIEW or DATASET;
%return; %return;
%end; %end;
%if %index(&libds,.)=0 %then %let libds=WORK.&libds; %if %index(&libds,.)=0 %then %let libds=WORK.&libds;
@@ -4089,6 +4130,7 @@ data _null_;
if _n_>&maxobs then stop; if _n_>&maxobs then stop;
%end; %end;
length _____str $32767; length _____str $32767;
call missing(_____str);
format _numeric_ best.; format _numeric_ best.;
format _character_ ; format _character_ ;
%local i comma var vtype vfmt; %local i comma var vtype vfmt;
@@ -4489,8 +4531,8 @@ filename &outref temp;
@param [in] targetds The target dataset against which to verify the query @param [in] targetds The target dataset against which to verify the query
@param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions @param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions
@param [out] outds= (work.mp_filtervalidate) Output dataset containing the @param [out] outds= (work.mp_filtervalidate) Output dataset containing the
error / warning message, if one exists. If this table contains any rows, err / warning message, if one exists. If this table contains any rows,
there are problems! there are problems!
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@@ -4674,17 +4716,17 @@ run;
%let vw=%mf_getuniquename(prefix=mp_getconstraints_vw_); %let vw=%mf_getuniquename(prefix=mp_getconstraints_vw_);
data &vw /view=&vw; data &vw /view=&vw;
set sashelp.vcncolu; set sashelp.vcncolu;
where TABLE_CATALOG="&lib"; where table_catalog="&lib";
/* use retain approach to reset the constraint order with each constraint */ /* use retain approach to reset the constraint order with each constraint */
length tmp $1000; length tmp $1000;
retain tmp; retain tmp;
drop tmp; drop tmp;
if tmp ne catx('|',libref,table_name,constraint_type,constraint_name) then do; if tmp ne catx('|',table_catalog,table_name,constraint_name) then do;
constraint_order=1; constraint_order=1;
end; end;
else constraint_order+1; else constraint_order+1;
tmp=catx('|',libref, table_name, constraint_type,constraint_name); tmp=catx('|',table_catalog, table_name,constraint_name);
run; run;
/* must use SQL as proc datasets does not support length changes */ /* must use SQL as proc datasets does not support length changes */
@@ -5194,7 +5236,7 @@ run;
%let curds=%scan(&dsnlist,&x); %let curds=%scan(&dsnlist,&x);
data _null_; data _null_;
file &fref mod; file &fref mod;
length nm lab $1024 typ $20; length lab $1024 typ $20;
set &colinfo (where=(upcase(memname)="&curds")) end=last; set &colinfo (where=(upcase(memname)="&curds")) end=last;
if _n_=1 then do; if _n_=1 then do;
@@ -6333,15 +6375,25 @@ filename &tempref clear;
%mend mp_include;/** %mend mp_include;/**
@file @file
@brief Initialise session with useful settings and variables @brief Initialise session with useful settings and variables
@details Implements a set of recommended options for general SAS use. This @details Implements a "strict" set of SAS options for use in defensive
macro is NOT used elsewhere within the core library (other than in tests), programming. Highly recommended, if you want your code to run on some
but it is used by the SASjs team when building web services for other machine.
SAS-Powered applications elsewhere.
If you have a good idea for an option, setting, or useful global variable - This macro is recommended to be compiled and invoked in the `initProgram`
feel free to [raise an issue](https://github.com/sasjs/core/issues/new)! for SASjs [Jobs](https://cli.sasjs.io/sasjsconfig.html#jobConfig_initProgram
), [Services](
https://cli.sasjs.io/sasjsconfig.html#serviceConfig_initProgram) and [Tests]
(https://cli.sasjs.io/sasjsconfig.html#testConfig_initProgram).
All global variables are prefixed with "SASJS_" (unless modfied with the For non SASjs projects, you could invoke in the autoexec, or in your own
solution initialisation macro.
If you have a good idea for another useful option, setting, or global
variable - feel free to [raise an issue](
https://github.com/sasjs/core/issues/new)!
All global variables are prefixed with "SASJS" (unless modified with the
prefix parameter). prefix parameter).
@param [in] prefix= (SASJS) The prefix to apply to the global macro variables @param [in] prefix= (SASJS) The prefix to apply to the global macro variables
@@ -6371,15 +6423,16 @@ filename &tempref clear;
autocorrect /* disallow mis-spelled procedure names */ autocorrect /* disallow mis-spelled procedure names */
compress=CHAR /* default is none so ensure we have something! */ compress=CHAR /* default is none so ensure we have something! */
datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */ datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */
errorcheck=STRICT /* catch errors in libname/filename statements */ %str(err)orcheck=STRICT /* catch errs in libname/filename statements */
fmterr /* ensure err when a format cannot be found */ fmterr /* ensure err when a format cannot be found */
mergenoby=%str(ERR)OR /* Throw err when a merge has no BY variables */ mergenoby=%str(ERR)OR /* throw err when a merge has no BY variables */
missing=. /* some sites change this which causes hard to detect errors */ missing=. /* changing this can cause hard to detect errs */
noquotelenmax /* avoid warnings for long strings */ noquotelenmax /* avoid warnings for long strings */
noreplace /* avoid overwriting permanent datasets */ noreplace /* avoid overwriting permanent datasets */
ps=max /* reduce log size slightly */ ps=max /* reduce log size slightly */
validmemname=COMPATIBLE /* avoid special characters etc in table names */ validmemname=COMPATIBLE /* avoid special characters etc in table names */
validvarname=V7 /* avoid special characters etc in variable names */ validvarname=V7 /* avoid special characters etc in variable names */
varinitchk=%str(ERR)OR /* avoid data mistakes from variable name typos */
varlenchk=%str(ERR)OR /* fail hard if truncation (data loss) can result */ varlenchk=%str(ERR)OR /* fail hard if truncation (data loss) can result */
; ;
@@ -6448,7 +6501,7 @@ filename &tempref clear;
%if &action=OPEN %then %do; %if &action=OPEN %then %do;
options nobomfile; options nobomfile;
data _null_;file &jref encoding='utf-8'; data _null_;file &jref encoding='utf-8';
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"'; put '{"PROCESSED_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '"';
run; run;
%end; %end;
%else %if (&action=ARR or &action=OBJ) %then %do; %else %if (&action=ARR or &action=OBJ) %then %do;
@@ -7010,7 +7063,7 @@ run;
%let abortme=1; %let abortme=1;
%end; %end;
/* catch errors - mp_abort must be called outside of a logic block */ /* catch errs - mp_abort must be called outside of a logic block */
%mp_abort(iftrue=(&abortme=1), %mp_abort(iftrue=(&abortme=1),
msg=%superq(msg), msg=%superq(msg),
mac=&sysmacroname mac=&sysmacroname
@@ -11112,7 +11165,7 @@ data _null_;
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
put ' data _null_;file &jref encoding=''utf-8''; '; put ' data _null_;file &jref encoding=''utf-8''; ';
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; '; put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
put ' run; '; put ' run; ';
put '%end; '; put '%end; ';
put '%else %if (&action=ARR or &action=OBJ) %then %do; '; put '%else %if (&action=ARR or &action=OBJ) %then %do; ';
@@ -16194,7 +16247,7 @@ data _null_;
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
put ' data _null_;file &jref encoding=''utf-8''; '; put ' data _null_;file &jref encoding=''utf-8''; ';
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; '; put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
put ' run; '; put ' run; ';
put '%end; '; put '%end; ';
put '%else %if (&action=ARR or &action=OBJ) %then %do; '; put '%else %if (&action=ARR or &action=OBJ) %then %do; ';
@@ -17418,6 +17471,8 @@ options noquotelenmax;
%local href cnt; %local href cnt;
%let cnt=0; %let cnt=0;
data _null_; data _null_;
length rel href $512;
call missing(rel,href);
set &libref1..links; set &libref1..links;
if rel='members' then do; if rel='members' then do;
url=cats("'","&base_uri",href,"?limit=10000'"); url=cats("'","&base_uri",href,"?limit=10000'");
@@ -17441,6 +17496,7 @@ options noquotelenmax;
libname &libref2 JSON fileref=&fname2; libname &libref2 JSON fileref=&fname2;
data &outds; data &outds;
length id $36 name $128 uri $64 type $32 description $256; length id $36 name $128 uri $64 type $32 description $256;
if _n_=1 then call missing (of _all_);
set &libref2..items; set &libref2..items;
run; run;
filename &fname2 clear; filename &fname2 clear;
@@ -17736,6 +17792,8 @@ data;run;
%local joburi; %local joburi;
%let joburi=0; %let joburi=0;
data _null_; data _null_;
length name uri $512;
call missing(name,uri);
set &foldermembers; set &foldermembers;
if name="&name" and uri=:'/jobDefinitions/definitions' if name="&name" and uri=:'/jobDefinitions/definitions'
then call symputx('joburi',uri); then call symputx('joburi',uri);
@@ -18892,6 +18950,8 @@ data;run;
%local joburi; %local joburi;
%let joburi=0; %let joburi=0;
data _null_; data _null_;
length name uri $512;
call missing(name,uri);
set &foldermembers; set &foldermembers;
if name="&name" and uri=:'/jobDefinitions/definitions' if name="&name" and uri=:'/jobDefinitions/definitions'
then call symputx('joburi',uri); then call symputx('joburi',uri);
@@ -19525,6 +19585,7 @@ run;
data &outds; data &outds;
format _program uri $128. state $32. stateDetails $32. timestamp datetime19. format _program uri $128. state $32. stateDetails $32. timestamp datetime19.
jobparams $32767.; jobparams $32767.;
call missing (of _all_);
stop; stop;
run; run;

View File

@@ -5,7 +5,7 @@
Run without arguments to see a list of detectable features. Run without arguments to see a list of detectable features.
Note - this list is based on known versions of SAS rather than Note - this list is based on known versions of SAS rather than
actual feature detection, as that is tricky / impossible to do actual feature detection, as that is tricky / impossible to do
without generating errors in most cases. without generating errs in most cases.
%put %mf_existfeature(PROCLUA); %put %mf_existfeature(PROCLUA);

View File

@@ -10,7 +10,7 @@
@param attr full list in [documentation]( @param attr full list in [documentation](
https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000147794.htm) https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000147794.htm)
@return output returns result of the attrc value supplied, or -1 and log @return output returns result of the attrc value supplied, or -1 and log
message if error. message if err.
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe

View File

@@ -10,7 +10,7 @@
@param attr Common values are NLOBS and NVARS, full list in [documentation]( @param attr Common values are NLOBS and NVARS, full list in [documentation](
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212040.htm) http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000212040.htm)
@return output returns result of the attrn value supplied, or -1 and log @return output returns result of the attrn value supplied, or -1 and log
message if error. message if err.
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe

33
base/mf_isint.sas Normal file
View File

@@ -0,0 +1,33 @@
/**
@file
@brief Returns 1 if the variable contains only digits 0-9, else 0
@details Note that numerics containing any punctuation (including decimals
or exponents) will be flagged zero.
If you'd like support for this, then do raise an issue (or even better, a
pull request!)
Usage:
%put %mf_isint(1) returns 1;
%put %mf_isint(1.1) returns 0;
%put %mf_isint(%str(1,1)) returns 0;
@param [in] arg input value to check
@version 9.2
**/
%macro mf_isint(arg
)/*/STORE SOURCE*/;
/* remove minus sign if exists */
%local val;
%if "%substr(%str(&arg),1,1)"="-" %then %let val=%substr(%str(&arg),2);
%else %let val=&arg;
/* check remaining chars */
%if %sysfunc(findc(%str(&val),,kd)) %then %do;0%end;
%else %do;1%end;
%mend mf_isint;

View File

@@ -51,7 +51,7 @@ Usage:
%end; %end;
/* /*
Now create the directory. Complain loudly of any errors. Now create the directory. Complain loudly of any errs.
*/ */
%let dname = %sysfunc(dcreate(&child, &parent)); %let dname = %sysfunc(dcreate(&child, &parent));

View File

@@ -12,7 +12,7 @@
@param libds library.dataset @param libds library.dataset
@return output returns result of the attrn value supplied, or log message @return output returns result of the attrn value supplied, or log message
if error. if err.
@version 9.2 @version 9.2

View File

@@ -54,6 +54,8 @@
/* create folders and copy content */ /* create folders and copy content */
data _null_; data _null_;
length msg $200;
call missing(msg);
set work.&tempds; set work.&tempds;
if _n_ = 1 then dpos+sum(length(directory),2); if _n_ = 1 then dpos+sum(length(directory),2);
filepath2="&target/"!!substr(filepath,dpos); filepath2="&target/"!!substr(filepath,dpos);
@@ -63,9 +65,9 @@
rc1=filename(fref1,filepath,'disk','recfm=n'); rc1=filename(fref1,filepath,'disk','recfm=n');
rc2=filename(fref2,filepath2,'disk','recfm=n'); rc2=filename(fref2,filepath2,'disk','recfm=n');
if fcopy(fref1,fref2) ne 0 then do; if fcopy(fref1,fref2) ne 0 then do;
sysmsg=sysmsg(); msg=sysmsg();
putlog "%str(ERR)OR: Unable to copy " filepath " to " filepath2; putlog "%str(ERR)OR: Unable to copy " filepath " to " filepath2;
putlog sysmg=; putlog msg=;
end; end;
end; end;
rc=filename(fref1); rc=filename(fref1);

View File

@@ -1,16 +1,22 @@
/** /**
@file @file
@brief Converts every value in a dataset to it's formatted value @brief Converts every value in a dataset to formatted value
@details Converts every value to it's formatted value. All variables will @details Converts every value to it's formatted value. All variables will
become character, and will be in the same order. become character, and will be in the same order as the original dataset.
Lengths will be adjusted according to the format lengths, where applicable.
Usage: Usage:
%mp_ds2fmtds(sashelp.cars,work.cars) %mp_ds2fmtds(sashelp.cars,work.cars)
%mp_ds2fmtds(sashelp.vallopt,vw_vallopt)
@param [in] libds The library.dataset to be converted @param [in] libds The library.dataset to be converted
@param [out] outds The dataset to create. @param [out] outds The dataset to create.
<h4> SAS Macros </h4>
@li mf_existds.sas
<h4> Related Macros <h4> <h4> Related Macros <h4>
@li mp_jsonout.sas @li mp_jsonout.sas
@@ -22,8 +28,9 @@
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
/* validations */ /* validations */
%if not %sysfunc(exist(&libds)) %then %do;
%put %str(WARN)ING: &libds does not exist; %if not %mf_existds(libds=&libds) %then %do;
%put %str(WARN)ING: &libds does not exist as either a VIEW or DATASET;
%return; %return;
%end; %end;
%if %index(&libds,.)=0 %then %let libds=WORK.&libds; %if %index(&libds,.)=0 %then %let libds=WORK.&libds;

View File

@@ -116,6 +116,7 @@ data _null_;
if _n_>&maxobs then stop; if _n_>&maxobs then stop;
%end; %end;
length _____str $32767; length _____str $32767;
call missing(_____str);
format _numeric_ best.; format _numeric_ best.;
format _character_ ; format _character_ ;
%local i comma var vtype vfmt; %local i comma var vtype vfmt;

View File

@@ -33,8 +33,8 @@
@param [in] targetds The target dataset against which to verify the query @param [in] targetds The target dataset against which to verify the query
@param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions @param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions
@param [out] outds= (work.mp_filtervalidate) Output dataset containing the @param [out] outds= (work.mp_filtervalidate) Output dataset containing the
error / warning message, if one exists. If this table contains any rows, err / warning message, if one exists. If this table contains any rows,
there are problems! there are problems!
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas

View File

@@ -48,17 +48,17 @@
%let vw=%mf_getuniquename(prefix=mp_getconstraints_vw_); %let vw=%mf_getuniquename(prefix=mp_getconstraints_vw_);
data &vw /view=&vw; data &vw /view=&vw;
set sashelp.vcncolu; set sashelp.vcncolu;
where TABLE_CATALOG="&lib"; where table_catalog="&lib";
/* use retain approach to reset the constraint order with each constraint */ /* use retain approach to reset the constraint order with each constraint */
length tmp $1000; length tmp $1000;
retain tmp; retain tmp;
drop tmp; drop tmp;
if tmp ne catx('|',libref,table_name,constraint_type,constraint_name) then do; if tmp ne catx('|',table_catalog,table_name,constraint_name) then do;
constraint_order=1; constraint_order=1;
end; end;
else constraint_order+1; else constraint_order+1;
tmp=catx('|',libref, table_name, constraint_type,constraint_name); tmp=catx('|',table_catalog, table_name,constraint_name);
run; run;
/* must use SQL as proc datasets does not support length changes */ /* must use SQL as proc datasets does not support length changes */

View File

@@ -139,7 +139,7 @@ run;
%let curds=%scan(&dsnlist,&x); %let curds=%scan(&dsnlist,&x);
data _null_; data _null_;
file &fref mod; file &fref mod;
length nm lab $1024 typ $20; length lab $1024 typ $20;
set &colinfo (where=(upcase(memname)="&curds")) end=last; set &colinfo (where=(upcase(memname)="&curds")) end=last;
if _n_=1 then do; if _n_=1 then do;

View File

@@ -1,15 +1,25 @@
/** /**
@file @file
@brief Initialise session with useful settings and variables @brief Initialise session with useful settings and variables
@details Implements a set of recommended options for general SAS use. This @details Implements a "strict" set of SAS options for use in defensive
macro is NOT used elsewhere within the core library (other than in tests), programming. Highly recommended, if you want your code to run on some
but it is used by the SASjs team when building web services for other machine.
SAS-Powered applications elsewhere.
If you have a good idea for an option, setting, or useful global variable - This macro is recommended to be compiled and invoked in the `initProgram`
feel free to [raise an issue](https://github.com/sasjs/core/issues/new)! for SASjs [Jobs](https://cli.sasjs.io/sasjsconfig.html#jobConfig_initProgram
), [Services](
https://cli.sasjs.io/sasjsconfig.html#serviceConfig_initProgram) and [Tests]
(https://cli.sasjs.io/sasjsconfig.html#testConfig_initProgram).
All global variables are prefixed with "SASJS_" (unless modfied with the For non SASjs projects, you could invoke in the autoexec, or in your own
solution initialisation macro.
If you have a good idea for another useful option, setting, or global
variable - feel free to [raise an issue](
https://github.com/sasjs/core/issues/new)!
All global variables are prefixed with "SASJS" (unless modified with the
prefix parameter). prefix parameter).
@param [in] prefix= (SASJS) The prefix to apply to the global macro variables @param [in] prefix= (SASJS) The prefix to apply to the global macro variables
@@ -39,15 +49,16 @@
autocorrect /* disallow mis-spelled procedure names */ autocorrect /* disallow mis-spelled procedure names */
compress=CHAR /* default is none so ensure we have something! */ compress=CHAR /* default is none so ensure we have something! */
datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */ datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */
errorcheck=STRICT /* catch errors in libname/filename statements */ %str(err)orcheck=STRICT /* catch errs in libname/filename statements */
fmterr /* ensure err when a format cannot be found */ fmterr /* ensure err when a format cannot be found */
mergenoby=%str(ERR)OR /* Throw err when a merge has no BY variables */ mergenoby=%str(ERR)OR /* throw err when a merge has no BY variables */
missing=. /* some sites change this which causes hard to detect errors */ missing=. /* changing this can cause hard to detect errs */
noquotelenmax /* avoid warnings for long strings */ noquotelenmax /* avoid warnings for long strings */
noreplace /* avoid overwriting permanent datasets */ noreplace /* avoid overwriting permanent datasets */
ps=max /* reduce log size slightly */ ps=max /* reduce log size slightly */
validmemname=COMPATIBLE /* avoid special characters etc in table names */ validmemname=COMPATIBLE /* avoid special characters etc in table names */
validvarname=V7 /* avoid special characters etc in variable names */ validvarname=V7 /* avoid special characters etc in variable names */
varinitchk=%str(ERR)OR /* avoid data mistakes from variable name typos */
varlenchk=%str(ERR)OR /* fail hard if truncation (data loss) can result */ varlenchk=%str(ERR)OR /* fail hard if truncation (data loss) can result */
; ;

View File

@@ -63,7 +63,7 @@
%if &action=OPEN %then %do; %if &action=OPEN %then %do;
options nobomfile; options nobomfile;
data _null_;file &jref encoding='utf-8'; data _null_;file &jref encoding='utf-8';
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"'; put '{"PROCESSED_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '"';
run; run;
%end; %end;
%else %if (&action=ARR or &action=OBJ) %then %do; %else %if (&action=ARR or &action=OBJ) %then %do;

View File

@@ -239,7 +239,7 @@ run;
%let abortme=1; %let abortme=1;
%end; %end;
/* catch errors - mp_abort must be called outside of a logic block */ /* catch errs - mp_abort must be called outside of a logic block */
%mp_abort(iftrue=(&abortme=1), %mp_abort(iftrue=(&abortme=1),
msg=%superq(msg), msg=%superq(msg),
mac=&sysmacroname mac=&sysmacroname

View File

@@ -95,7 +95,7 @@ data _null_;
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
put ' data _null_;file &jref encoding=''utf-8''; '; put ' data _null_;file &jref encoding=''utf-8''; ';
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; '; put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
put ' run; '; put ' run; ';
put '%end; '; put '%end; ';
put '%else %if (&action=ARR or &action=OBJ) %then %do; '; put '%else %if (&action=ARR or &action=OBJ) %then %do; ';

View File

@@ -0,0 +1,33 @@
/**
@file
@brief Testing mf_isint macro
<h4> SAS Macros </h4>
@li mf_isint.sas
@li mp_assert.sas
**/
%mp_assert(
iftrue=(
"%mf_isint(1)"="1"
),
desc=Checking basic mf_isint(1),
outds=work.test_results
)
%mp_assert(
iftrue=(
"%mf_isint(1.1)"="0"
),
desc=Checking basic mf_isint(1.1),
outds=work.test_results
)
%mp_assert(
iftrue=(
"%mf_isint(-1)"="1"
),
desc=Checking mf_isint(-1),
outds=work.test_results
)

View File

@@ -15,10 +15,12 @@ filename inc temp;
data _null_; data _null_;
set work.test; set work.test;
file inc; file inc;
line=cats('%mp_ds2fmtds(sashelp.',memname,',',memname,')'); libds=cats('sashelp.',memname);
if exist(libds) then line=cats('%mp_ds2fmtds(',libds,',',memname,')');
put line; put line;
run; run;
options obs=50;
%inc inc; %inc inc;
%mp_assert( %mp_assert(

View File

@@ -33,6 +33,7 @@ run;
%put TEST1: checking web service code; %put TEST1: checking web service code;
data work.test_results; data work.test_results;
length test_description $256 test_result $4 test_comments $256; length test_description $256 test_result $4 test_comments $256;
if _n_=1 then call missing (of _all_);
infile compare end=eof; infile compare end=eof;
input; input;
if eof then do; if eof then do;

View File

@@ -243,7 +243,7 @@ data _null_;
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
put ' data _null_;file &jref encoding=''utf-8''; '; put ' data _null_;file &jref encoding=''utf-8''; ';
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; '; put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
put ' run; '; put ' run; ';
put '%end; '; put '%end; ';
put '%else %if (&action=ARR or &action=OBJ) %then %do; '; put '%else %if (&action=ARR or &action=OBJ) %then %do; ';

View File

@@ -100,6 +100,8 @@ options noquotelenmax;
%local href cnt; %local href cnt;
%let cnt=0; %let cnt=0;
data _null_; data _null_;
length rel href $512;
call missing(rel,href);
set &libref1..links; set &libref1..links;
if rel='members' then do; if rel='members' then do;
url=cats("'","&base_uri",href,"?limit=10000'"); url=cats("'","&base_uri",href,"?limit=10000'");
@@ -123,6 +125,7 @@ options noquotelenmax;
libname &libref2 JSON fileref=&fname2; libname &libref2 JSON fileref=&fname2;
data &outds; data &outds;
length id $36 name $128 uri $64 type $32 description $256; length id $36 name $128 uri $64 type $32 description $256;
if _n_=1 then call missing (of _all_);
set &libref2..items; set &libref2..items;
run; run;
filename &fname2 clear; filename &fname2 clear;

View File

@@ -92,6 +92,8 @@ data;run;
%local joburi; %local joburi;
%let joburi=0; %let joburi=0;
data _null_; data _null_;
length name uri $512;
call missing(name,uri);
set &foldermembers; set &foldermembers;
if name="&name" and uri=:'/jobDefinitions/definitions' if name="&name" and uri=:'/jobDefinitions/definitions'
then call symputx('joburi',uri); then call symputx('joburi',uri);

View File

@@ -115,6 +115,8 @@ data;run;
%local joburi; %local joburi;
%let joburi=0; %let joburi=0;
data _null_; data _null_;
length name uri $512;
call missing(name,uri);
set &foldermembers; set &foldermembers;
if name="&name" and uri=:'/jobDefinitions/definitions' if name="&name" and uri=:'/jobDefinitions/definitions'
then call symputx('joburi',uri); then call symputx('joburi',uri);

View File

@@ -168,6 +168,7 @@ run;
data &outds; data &outds;
format _program uri $128. state $32. stateDetails $32. timestamp datetime19. format _program uri $128. state $32. stateDetails $32. timestamp datetime19.
jobparams $32767.; jobparams $32767.;
call missing (of _all_);
stop; stop;
run; run;