mirror of
https://github.com/sasjs/core.git
synced 2026-01-16 13:00:05 +00:00
feat: new macros (mp_reseterror and mp_init), new datetime format added to mp_getcols, and stub prepared for mp_makedata
This commit is contained in:
@@ -51,7 +51,7 @@ data &outds(keep=name type length varnum format label ddtype);
|
|||||||
else if formatd=0 then format=cats(format2,formatl,'.');
|
else if formatd=0 then format=cats(format2,formatl,'.');
|
||||||
else format=cats(format2,formatl,'.',formatd);
|
else format=cats(format2,formatl,'.',formatd);
|
||||||
type='N';
|
type='N';
|
||||||
if format=:'DATETIME' then ddtype='DATETIME';
|
if format=:'DATETIME' or format=:'E8601DT' then ddtype='DATETIME';
|
||||||
else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY'
|
else if format=:'DATE' or format=:'DDMMYY' or format=:'MMDDYY'
|
||||||
or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA'
|
or format=:'YYMMDD' or format=:'E8601DA' or format=:'B8601DA'
|
||||||
or format=:'MONYY'
|
or format=:'MONYY'
|
||||||
|
|||||||
54
base/mp_init.sas
Normal file
54
base/mp_init.sas
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Initialise session with useful settings and variables
|
||||||
|
@details Implements a set of recommended options for general SAS use. This
|
||||||
|
macro is NOT used elsewhere within the core library (other than in tests),
|
||||||
|
but it is used by the SASjs team when building web services for
|
||||||
|
SAS-Powered applications elsewhere.
|
||||||
|
|
||||||
|
If you have a good idea for an option, setting, or useful global variable -
|
||||||
|
feel free to [raise an issue](https://github.com/sasjs/core/issues/new)!
|
||||||
|
|
||||||
|
All global variables are prefixed with "SASJS_" (unless modfied with the
|
||||||
|
prefix parameter).
|
||||||
|
|
||||||
|
@param [in] prefix= (SASJS) The prefix to apply to the global macro variables
|
||||||
|
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_init(prefix=
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%global
|
||||||
|
&prefix._INIT_NUM /* initialisation time as numeric */
|
||||||
|
&prefix._INIT_DTTM /* initialisation time in E8601DT26.6 format */
|
||||||
|
;
|
||||||
|
%if %eval(&&&prefix._INIT_NUM>0) %then %return; /* only run once */
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
dttm=datetime();
|
||||||
|
call symputx("&prefix._init_num",dttm);
|
||||||
|
call symputx("&prefix._init_dttm",put(dttm,E8601DT26.6));
|
||||||
|
run;
|
||||||
|
|
||||||
|
options
|
||||||
|
autocorrect /* disallow mis-spelled procedure names */
|
||||||
|
compress=CHAR /* default is none so ensure we have something! */
|
||||||
|
datastmtchk=ALLKEYWORDS /* protection from overwriting input datasets */
|
||||||
|
errorcheck=STRICT /* catch errors in libname/filename statements */
|
||||||
|
fmterr /* ensure error when a format cannot be found */
|
||||||
|
mergenoby=ERROR /*
|
||||||
|
missing=. /* some sites change this which causes hard to detect errors */
|
||||||
|
noquotelenmax /* avoid warnings for long strings */
|
||||||
|
noreplace /* avoid overwriting permanent datasets */
|
||||||
|
ps=max /* reduce log size slightly */
|
||||||
|
validmemname=COMPATIBLE /* avoid special characters etc in table names */
|
||||||
|
validvarname=V7 /* avoid special characters etc in variable names */
|
||||||
|
varlenchk=ERROR /* fail hard if truncation (data loss) can result */
|
||||||
|
;
|
||||||
|
|
||||||
|
%mend mp_init;
|
||||||
45
base/mp_makedata.sas
Normal file
45
base/mp_makedata.sas
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Create sample data based on the structure of an empty table
|
||||||
|
@details Many SAS projects involve sensitive datasets. One way to _ensure_
|
||||||
|
the data is anonymised, is never to receive it in the first place! Often
|
||||||
|
consultants are provided with empty tables, and expected to create complex
|
||||||
|
ETL flows.
|
||||||
|
|
||||||
|
This macro can help by taking an empty table, and populating it with data
|
||||||
|
according to the variable types and formats.
|
||||||
|
|
||||||
|
The primary key is respected, as well as any NOT NULL constraints.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
create table work.example(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
DD_TYPE char(16),
|
||||||
|
DD_SOURCE char(2048),
|
||||||
|
DD_SHORTDESC char(256),
|
||||||
|
constraint pk primary key(tx_from, dd_type,dd_source),
|
||||||
|
constraint nnn not null(DD_SHORTDESC)
|
||||||
|
);
|
||||||
|
%mp_makedata(work.example)
|
||||||
|
|
||||||
|
@param [in] libds The empty table in which to create data
|
||||||
|
@param [out] obs= (500) The number of records to create.
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_nobs.sas
|
||||||
|
@li mp_getcols.sas
|
||||||
|
@li mp_getpk.sas
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_makedata(libds
|
||||||
|
,obs=500
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
|
||||||
|
%mend mp_makedata;
|
||||||
27
base/mp_reseterror.sas
Normal file
27
base/mp_reseterror.sas
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Reset when an err condition occurs
|
||||||
|
@details When building apps, sometimes an operation must be attempted that
|
||||||
|
can cause an err condition. There is no try catch in SAS! So the err state
|
||||||
|
must be caught and reset.
|
||||||
|
|
||||||
|
This macro attempts to do that reset.
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_reseterror(
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
options obs=max replace nosyntaxcheck;
|
||||||
|
%let syscc=0;
|
||||||
|
|
||||||
|
%if "&sysprocessmode " = "SAS Stored Process Server " %then %do;
|
||||||
|
data _null_;
|
||||||
|
rc=stpsrvset('program error', 0);
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend mp_reseterror;
|
||||||
24
tests/crossplatform/mp_init.test.sas
Normal file
24
tests/crossplatform/mp_init.test.sas
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_gsubfile.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_init.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 1 - mp_init.sas actually already ran as part of testinit
|
||||||
|
* So lets test to make sure it will not run again
|
||||||
|
*/
|
||||||
|
|
||||||
|
%let initial_value=&sasjs_init_num;
|
||||||
|
|
||||||
|
%mp_init();
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=("&initial_value"="&sasjs_init_num"),
|
||||||
|
desc=Check that mp_init() did not run twice,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_lockfilecheck.sas
|
@li mp_lockfilecheck.sas
|
||||||
@li mp_assert.sas
|
@li mp_assert.sas
|
||||||
|
@li mp_reseterror.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -29,6 +30,8 @@ data work.test; a=1;run;
|
|||||||
|
|
||||||
%mp_lockfilecheck(sashelp.class)
|
%mp_lockfilecheck(sashelp.class)
|
||||||
|
|
||||||
|
%mp_reseterror()
|
||||||
|
|
||||||
%mp_assert(
|
%mp_assert(
|
||||||
iftrue=(&success=1),
|
iftrue=(&success=1),
|
||||||
desc=Checking sashelp table cannot be locked,
|
desc=Checking sashelp table cannot be locked,
|
||||||
|
|||||||
23
tests/crossplatform/mp_reseterror.test.sas
Normal file
23
tests/crossplatform/mp_reseterror.test.sas
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_reseterror macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_reseterror.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
/* cause an error */
|
||||||
|
|
||||||
|
lock sashelp.class;
|
||||||
|
|
||||||
|
/* recover ? */
|
||||||
|
%mp_reseterror()
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&success=1),
|
||||||
|
desc=Checking sashelp table cannot be locked,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -2,11 +2,17 @@
|
|||||||
@file
|
@file
|
||||||
@brief init file for tests
|
@brief init file for tests
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_init.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/* location in metadata or SAS Drive for temporary files */
|
/* location in metadata or SAS Drive for temporary files */
|
||||||
%let mcTestAppLoc=/Public/temp/macrocore;
|
%let mcTestAppLoc=/Public/temp/macrocore;
|
||||||
|
|
||||||
|
/* set defaults */
|
||||||
|
%mp_init()
|
||||||
|
|
||||||
%macro loglevel();
|
%macro loglevel();
|
||||||
%if &_debug=2477 %then %do;
|
%if &_debug=2477 %then %do;
|
||||||
options mprint;
|
options mprint;
|
||||||
|
|||||||
Reference in New Issue
Block a user