mirror of
https://github.com/sasjs/core.git
synced 2025-12-20 09:41:20 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e3c333ea39 | |||
| ae72446f85 | |||
| 2b6bf4bd02 | |||
| 6dbb3760e0 | |||
| 200d9a5761 | |||
|
|
01a9a5b823 | ||
|
|
35eadd0e9d | ||
| 5cdca95216 | |||
|
|
81b75a32ed | ||
| b7f5a2ec00 | |||
| db859bbf1d | |||
| 27b56e8efd | |||
| 28ea218d02 | |||
| f356e1f351 | |||
| 4b375e0b8c | |||
| 7db207dd1c |
44
.githooks/pre-commit
Executable file
44
.githooks/pre-commit
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# A hook script to verify that no filenames with capital letters are committed.
|
||||||
|
# Called by "git commit" with no arguments. The hook should
|
||||||
|
# exit with non-zero status after issuing an appropriate message if
|
||||||
|
# it wants to stop the commit.
|
||||||
|
#
|
||||||
|
# Go through all the changed files (except for deleted and unmerged)
|
||||||
|
|
||||||
|
# Save exit code of last executed action
|
||||||
|
exit_code=0
|
||||||
|
|
||||||
|
# Check if file is one of SAS|DDL|CSV|SH and check for uppercase letters
|
||||||
|
mime_pattern="\.(sas|ddl|csv|sh)"
|
||||||
|
# Check for capital letters only in file names
|
||||||
|
extra_pattern="(^|/)[^/]*([A-Z]+)[^/]*\.[A-Za-z]{3}$"
|
||||||
|
# Grep git diff of files to commit
|
||||||
|
files=$( git diff --cached --find-copies --find-renames --name-only --diff-filter=ACMRTXBU |
|
||||||
|
grep -Ei "$mime_pattern" |
|
||||||
|
grep -E "$extra_pattern" )
|
||||||
|
echo "$files"
|
||||||
|
if [[ -n "$files" ]];
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo "Found files that contain capital letters."
|
||||||
|
echo "Please rename the following files in lowercase, and commit again:"
|
||||||
|
|
||||||
|
for file in $files; do
|
||||||
|
echo -e '- \E[0;32m'"$file"'\033[0m'
|
||||||
|
done
|
||||||
|
# Abort commit
|
||||||
|
exit_code=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$exit_code" == "0" ]; then
|
||||||
|
echo
|
||||||
|
echo -e '\033[1m'"Pre-commit validation Passed"'\033[0m'
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo -e '\033[1m'"Commit Aborted!"'\033[0m'
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
exit $exit_code
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,3 +1,9 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.DS_Store
|
.DS_Store
|
||||||
sasjsbuild/
|
sasjsbuild/
|
||||||
|
|
||||||
|
# avoid filenames with spaces being committed to source control
|
||||||
|
**\ **
|
||||||
|
|
||||||
|
# ignore the mc_* files - containing macros for individual libraries
|
||||||
|
mc_*
|
||||||
@@ -5,4 +5,4 @@ image:
|
|||||||
file: .gitpod.dockerfile
|
file: .gitpod.dockerfile
|
||||||
vscode:
|
vscode:
|
||||||
extensions:
|
extensions:
|
||||||
- sasjs.sasjs-for-vscode@1.4.3:LY5VLf6H5R3u7nqVRnCQRw==
|
- sasjs.sasjs-for-vscode@1.6.0:V4hJpMtbpekMcPRNhh4SXQ==
|
||||||
9
.vscode/.editorconfig
vendored
Normal file
9
.vscode/.editorconfig
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"search.exclude": {
|
||||||
|
"**/sasjsbuild/**": true,
|
||||||
|
"**/dist/**":true
|
||||||
|
},
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"trim_trailing_whitespace": true
|
||||||
|
}
|
||||||
10
.vscode/settings.json
vendored
Normal file
10
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.detectIndentation": true,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.rulers": [
|
||||||
|
80
|
||||||
|
],
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
}
|
||||||
@@ -27,6 +27,5 @@ To contribute:
|
|||||||
1. Create your feature branch (`git checkout -b myfeature`)
|
1. Create your feature branch (`git checkout -b myfeature`)
|
||||||
2. Make your change
|
2. Make your change
|
||||||
3. Update the `all.sas` file (`python3 build.py`)
|
3. Update the `all.sas` file (`python3 build.py`)
|
||||||
4. Commit the change, using the [conventional commit](https://www.conventionalcommits.org/en/v1.0.0) standard
|
4. Push and make a PR
|
||||||
5. Push and make a PR
|
|
||||||
|
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Macro Core
|
# Macro Core
|
||||||
|
|
||||||
Much quality. Many standards. The **Macro Core** library exists to save time and development effort! Herein ye shall find a veritable host of MIT-licenced, production quality SAS macros. These are a mix of tools, utilities, functions and code generators that are useful in the context of Application Development on the SAS platform (eg https://datacontroller.io). [Contributions](https://github.com/sasjs/core/blob/main/CONTRIBUTING.md) are welcomed.
|
Much quality. Many standards. The **Macro Core** library exists to save time and development effort! Herein ye shall find a veritable host of MIT-licenced, production quality SAS macros. These are a mix of tools, utilities, functions and code generators that are useful in the context of [Application Development](https://sasapps.io) on the SAS platform (eg https://datacontroller.io). [Contributions](https://github.com/sasjs/core/blob/main/CONTRIBUTING.md) are welcomed.
|
||||||
|
|
||||||
You can download and compile them all in just two lines of SAS code:
|
You can download and compile them all in just two lines of SAS code:
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
|||||||
%inc mc;
|
%inc mc;
|
||||||
```
|
```
|
||||||
|
|
||||||
Documentation: https://sasjs.github.io/core.github.io/files.html
|
Documentation: https://core.sasjs.io
|
||||||
|
|
||||||
# Components
|
# Components
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
|||||||
## File Properties
|
## File Properties
|
||||||
|
|
||||||
- filenames much match macro names
|
- filenames much match macro names
|
||||||
- filenames must be lowercase
|
- filenames must be lowercase, without spaces
|
||||||
- macro names must be lowercase
|
- macro names must be lowercase
|
||||||
- one macro per file
|
- one macro per file
|
||||||
- prefixes:
|
- prefixes:
|
||||||
@@ -99,7 +99,7 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
|||||||
- unix style line endings (lf)
|
- unix style line endings (lf)
|
||||||
- individual lines should be no more than 80 characters long
|
- individual lines should be no more than 80 characters long
|
||||||
- UTF-8
|
- UTF-8
|
||||||
- no trailing white space
|
|
||||||
|
|
||||||
## Header Properties
|
## Header Properties
|
||||||
|
|
||||||
@@ -136,13 +136,15 @@ When contributing to this library, it is therefore important to ensure that all
|
|||||||
## Coding Standards
|
## Coding Standards
|
||||||
|
|
||||||
- Indentation = 2 spaces. No tabs!
|
- Indentation = 2 spaces. No tabs!
|
||||||
|
- no trailing white space
|
||||||
|
- no invisible characters, other than spaces. If invisibles are needed, use hex literals.
|
||||||
- Macro variables should not have the trailing dot (`&var` not `&var.`) unless necessary to prevent incorrect resolution
|
- Macro variables should not have the trailing dot (`&var` not `&var.`) unless necessary to prevent incorrect resolution
|
||||||
- The closing `%mend;` should not contain the macro name.
|
- The closing `%mend;` should **not** contain the macro name.
|
||||||
- All macros should be defined with brackets, even if no variables are needed - ie `%macro x();` not `%macro x;`
|
- All macros should be defined with brackets, even if no variables are needed - ie `%macro x();` not `%macro x;`
|
||||||
- Mandatory parameters should be positional, all optional parameters should be keyword (var=) style.
|
- Mandatory parameters should be positional, all optional parameters should be keyword (var=) style.
|
||||||
- All dataset references must be 2 level (eg `work.blah`, not `blah`). This is to avoid contention when options [DATASTMTCHK](https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000279064.htm)=ALLKEYWORDS is in effect.
|
- All dataset references must be 2 level (eg `work.blah`, not `blah`). This is to avoid contention when options [DATASTMTCHK](https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000279064.htm)=ALLKEYWORDS is in effect.
|
||||||
- Avoid naming collisions! All macro variables should be local scope. Use system generated work tables where possible - eg `data ; set sashelp.class; run; data &output; set &syslast; run;`
|
- Avoid naming collisions! All macro variables should be local scope. Use system generated work tables where possible - eg `data ; set sashelp.class; run; data &output; set &syslast; run;`
|
||||||
- If you have a long-running SQL query, the use of a `quit;` statement is recommended in order to benefit from the timing statistics.
|
- The use of `quit;` for `proc sql` is optional unless you are looking to benefit from the timing statistics.
|
||||||
|
|
||||||
# General Notes
|
# General Notes
|
||||||
|
|
||||||
|
|||||||
172
all.sas
172
all.sas
@@ -1426,12 +1426,12 @@ Usage:
|
|||||||
|
|
||||||
%mend;/**
|
%mend;/**
|
||||||
@file
|
@file
|
||||||
@brief Creates a Unique ID based on system time in a friendly format
|
@brief Creates a unique ID based on system time in friendly format
|
||||||
@details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits>
|
@details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits>
|
||||||
|
|
||||||
%put %mf_uid();
|
%put %mf_uid();
|
||||||
|
|
||||||
@version 9.2
|
@version 9.3
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
**/
|
**/
|
||||||
@@ -1440,7 +1440,7 @@ Usage:
|
|||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local today now;
|
%local today now;
|
||||||
%let today=%sysfunc(today(),yymmddn8.);
|
%let today=%sysfunc(today(),yymmddn8.);
|
||||||
%let now=%sysfunc(compress(%sysfunc(time(),time12.3),:.));
|
%let now=%sysfunc(compress(%sysfunc(time(),tod12.3),:.));
|
||||||
|
|
||||||
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
|
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
|
||||||
|
|
||||||
@@ -7601,6 +7601,98 @@ run;
|
|||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%mend;
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Deletes a library by Name
|
||||||
|
|
||||||
|
@details Used to delete a library.
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%* create a library in the home directory ;
|
||||||
|
%mm_createlibrary(
|
||||||
|
libname=My Temp Library,
|
||||||
|
libref=XXTEMPXX,
|
||||||
|
tree=/User Folders/&sysuserid,
|
||||||
|
directory=%sysfunc(pathname(work))
|
||||||
|
)
|
||||||
|
|
||||||
|
%* delete the library ;
|
||||||
|
%mm_deletelibrary(name=My Temp Library)
|
||||||
|
|
||||||
|
After running the above, the following will be shown in the log:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
@param [in] name= the name (not libref) of the library to be deleted
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
|
||||||
|
@version 9.4
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mm_deletelibrary(
|
||||||
|
name=
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if library exists and get uri
|
||||||
|
*/
|
||||||
|
data _null_;
|
||||||
|
length type uri $256;
|
||||||
|
rc=metadata_resolve("omsobj:SASLibrary?@Name='&name'",type,uri);
|
||||||
|
call symputx('checktype',type,'l');
|
||||||
|
call symputx('liburi',uri,'l');
|
||||||
|
putlog (_all_)(=);
|
||||||
|
run;
|
||||||
|
%if &checktype ne SASLibrary %then %do;
|
||||||
|
%put &sysmacroname: Library (&name) was not found, and so will not be deleted;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%local fname1 fname2;
|
||||||
|
%let fname1=%mf_getuniquefileref();
|
||||||
|
%let fname2=%mf_getuniquefileref();
|
||||||
|
|
||||||
|
filename &fname1 temp lrecl=10000;
|
||||||
|
filename &fname2 temp lrecl=10000;
|
||||||
|
data _null_ ;
|
||||||
|
file &fname1 ;
|
||||||
|
put "<DeleteMetadata><Metadata><SASLibrary Id='&liburi'/>";
|
||||||
|
put "</Metadata><NS>SAS</NS><Flags>268436480</Flags><Options/>";
|
||||||
|
put "</DeleteMetadata>";
|
||||||
|
run ;
|
||||||
|
proc metadata in=&fname1 out=&fname2 verbose;run;
|
||||||
|
|
||||||
|
/* list the result */
|
||||||
|
data _null_;infile &fname2; input; list; run;
|
||||||
|
|
||||||
|
filename &fname1 clear;
|
||||||
|
filename &fname2 clear;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check deletion
|
||||||
|
*/
|
||||||
|
%local isgone;
|
||||||
|
data _null_;
|
||||||
|
length type uri $256;
|
||||||
|
rc=metadata_resolve("omsobj:SASLibrary?@Id='&liburi'",type,uri);
|
||||||
|
call symputx('isgone',type,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&isgone = SASLibrary)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Library (&name) NOT deleted)
|
||||||
|
)
|
||||||
|
|
||||||
|
%put &sysmacroname: Library &name (&liburi) was successfully deleted;
|
||||||
|
|
||||||
%mend;
|
%mend;
|
||||||
/**
|
/**
|
||||||
@file mm_deletestp.sas
|
@file mm_deletestp.sas
|
||||||
@@ -8453,6 +8545,39 @@ run;
|
|||||||
options metarepository=&oldrepo;
|
options metarepository=&oldrepo;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%mend;/**
|
||||||
|
@file
|
||||||
|
@brief Compares the metadata of a library with the physical tables
|
||||||
|
|
||||||
|
@param [out] prefix the dataset to create that contains the list of libraries
|
||||||
|
@param mDebug set to anything but 0 to show debug messages in the log
|
||||||
|
|
||||||
|
@test Create a temporary library as follows:
|
||||||
|
|
||||||
|
%
|
||||||
|
|
||||||
|
@details Creates a series of output tables that show the differences between
|
||||||
|
metadata and physical tables.
|
||||||
|
Each output can be created with an optional prefix.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mm_getlibmetadiffs
|
||||||
|
prefix=metadiff
|
||||||
|
,mdebug=0
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%if &mdebug = 0 %then %let mdebug=*;
|
||||||
|
|
||||||
|
&mdebug %put _local_;
|
||||||
|
|
||||||
|
|
||||||
%mend;/**
|
%mend;/**
|
||||||
@file
|
@file
|
||||||
@brief Creates a dataset with all metadata libraries
|
@brief Creates a dataset with all metadata libraries
|
||||||
@@ -13910,6 +14035,8 @@ libname &libref;
|
|||||||
@li sas_services - will use oauth_bearer=sas_services
|
@li sas_services - will use oauth_bearer=sas_services
|
||||||
@param [in] inds= The input dataset containing a list of jobs and parameters
|
@param [in] inds= The input dataset containing a list of jobs and parameters
|
||||||
@param [in] maxconcurrency= The max number of parallel jobs to run. Default=8.
|
@param [in] maxconcurrency= The max number of parallel jobs to run. Default=8.
|
||||||
|
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
|
||||||
|
succcessfully
|
||||||
@param [in] mdebug= set to 1 to enable DEBUG messages
|
@param [in] mdebug= set to 1 to enable DEBUG messages
|
||||||
@param [out] outds= The output dataset containing the results
|
@param [out] outds= The output dataset containing the results
|
||||||
@param [out] outref= The output fileref to which to append the log file(s).
|
@param [out] outref= The output fileref to which to append the log file(s).
|
||||||
@@ -13933,6 +14060,7 @@ libname &libref;
|
|||||||
,access_token_var=ACCESS_TOKEN
|
,access_token_var=ACCESS_TOKEN
|
||||||
,grant_type=sas_services
|
,grant_type=sas_services
|
||||||
,outref=0
|
,outref=0
|
||||||
|
,raise_err=0
|
||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
@@ -14111,7 +14239,8 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
%end;
|
%end;
|
||||||
%if &jid=&jcnt %then %do;
|
%if &jid=&jcnt %then %do;
|
||||||
/* we are at the end of the loop - time to see which jobs have finished */
|
/* we are at the end of the loop - time to see which jobs have finished */
|
||||||
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref)
|
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref
|
||||||
|
,raise_err=&raise_err)
|
||||||
%local done;
|
%local done;
|
||||||
%let done=%mf_nobs(&jdswaitfor);
|
%let done=%mf_nobs(&jdswaitfor);
|
||||||
%if &done>0 %then %do;
|
%if &done>0 %then %do;
|
||||||
@@ -14218,6 +14347,8 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
following format: `/jobExecution/jobs/&JOBID./state` and the corresponding
|
following format: `/jobExecution/jobs/&JOBID./state` and the corresponding
|
||||||
job name. The uri should be in a `uri` variable, and the job path/name
|
job name. The uri should be in a `uri` variable, and the job path/name
|
||||||
should be in a `_program` variable.
|
should be in a `_program` variable.
|
||||||
|
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
|
||||||
|
succcessfully
|
||||||
@param [out] outds= The output dataset containing the list of states by job
|
@param [out] outds= The output dataset containing the list of states by job
|
||||||
(default=work.mv_jobexecute)
|
(default=work.mv_jobexecute)
|
||||||
@param [out] outref= A fileref to which the spawned job logs should be appended.
|
@param [out] outref= A fileref to which the spawned job logs should be appended.
|
||||||
@@ -14229,6 +14360,7 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquelibref.sas
|
||||||
@li mf_existvar.sas
|
@li mf_existvar.sas
|
||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mv_getjoblog.sas
|
@li mv_getjoblog.sas
|
||||||
@@ -14241,6 +14373,7 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
,inds=0
|
,inds=0
|
||||||
,outds=work.mv_jobwaitfor
|
,outds=work.mv_jobwaitfor
|
||||||
,outref=0
|
,outref=0
|
||||||
|
,raise_err=0
|
||||||
);
|
);
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
@@ -14284,7 +14417,7 @@ options noquotelenmax;
|
|||||||
data _null_;
|
data _null_;
|
||||||
length jobparams $32767;
|
length jobparams $32767;
|
||||||
set &inds end=last;
|
set &inds end=last;
|
||||||
call symputx(cats('joburi',_n_),substr(uri,1,55)!!'/state','l');
|
call symputx(cats('joburi',_n_),substr(uri,1,55),'l');
|
||||||
call symputx(cats('jobname',_n_),_program,'l');
|
call symputx(cats('jobname',_n_),_program,'l');
|
||||||
call symputx(cats('jobparams',_n_),jobparams,'l');
|
call symputx(cats('jobparams',_n_),jobparams,'l');
|
||||||
if last then call symputx('uricnt',_n_,'l');
|
if last then call symputx('uricnt',_n_,'l');
|
||||||
@@ -14299,7 +14432,7 @@ run;
|
|||||||
%let fname0=%mf_getuniquefileref();
|
%let fname0=%mf_getuniquefileref();
|
||||||
|
|
||||||
data &outds;
|
data &outds;
|
||||||
format _program uri $128. state $32. timestamp datetime19. jobparams $32767.;
|
format _program uri $128. state $32. stateDetails $32. timestamp datetime19. jobparams $32767.;
|
||||||
stop;
|
stop;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
@@ -14307,7 +14440,7 @@ run;
|
|||||||
%do i=1 %to &uricnt;
|
%do i=1 %to &uricnt;
|
||||||
%if "&&joburi&i" ne "0" %then %do;
|
%if "&&joburi&i" ne "0" %then %do;
|
||||||
proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&&joburi&i";
|
proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&&joburi&i";
|
||||||
headers "Accept"="text/plain"
|
headers "Accept"="application/json"
|
||||||
%if &grant_type=authorization_code %then %do;
|
%if &grant_type=authorization_code %then %do;
|
||||||
"Authorization"="Bearer &&&access_token_var"
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
%end; ;
|
%end; ;
|
||||||
@@ -14321,12 +14454,20 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%let status=notset;
|
%let status=notset;
|
||||||
|
|
||||||
|
%local libref1;
|
||||||
|
%let libref1=%mf_getuniquelibref();
|
||||||
|
libname &libref1 json fileref=&fname0;
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname0;
|
length state stateDetails $32;
|
||||||
input;
|
set &libref1..root;
|
||||||
call symputx('status',_infile_,'l');
|
call symputx('status',state,'l');
|
||||||
|
call symputx('stateDetails',stateDetails,'l');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
libname &libref1 clear;
|
||||||
|
|
||||||
%if &status=completed or &status=failed or &status=canceled %then %do;
|
%if &status=completed or &status=failed or &status=canceled %then %do;
|
||||||
%local plainuri;
|
%local plainuri;
|
||||||
%let plainuri=%substr(&&joburi&i,1,55);
|
%let plainuri=%substr(&&joburi&i,1,55);
|
||||||
@@ -14335,6 +14476,7 @@ run;
|
|||||||
_program="&&jobname&i",
|
_program="&&jobname&i",
|
||||||
uri="&plainuri",
|
uri="&plainuri",
|
||||||
state="&status",
|
state="&status",
|
||||||
|
stateDetails=symget("stateDetails"),
|
||||||
timestamp=datetime(),
|
timestamp=datetime(),
|
||||||
jobparams=symget("jobparams&i");
|
jobparams=symget("jobparams&i");
|
||||||
%let joburi&i=0; /* do not re-check */
|
%let joburi&i=0; /* do not re-check */
|
||||||
@@ -14353,6 +14495,16 @@ run;
|
|||||||
,msg=%str(status &status not expected!!)
|
,msg=%str(status &status not expected!!)
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%if (&raise_err) %then %do;
|
||||||
|
%if (&status = canceled or &status = failed or %length(&stateDetails)>0) %then %do;
|
||||||
|
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
|
||||||
|
%else %let SYSCC=5;
|
||||||
|
%put %str(ERR)OR: Job &&jobname&i. did not complete successfully. &stateDetails;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
%if &i=&uricnt %then %do;
|
%if &i=&uricnt %then %do;
|
||||||
%local goback;
|
%local goback;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Creates a Unique ID based on system time in a friendly format
|
@brief Creates a unique ID based on system time in friendly format
|
||||||
@details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits>
|
@details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits>
|
||||||
|
|
||||||
%put %mf_uid();
|
%put %mf_uid();
|
||||||
|
|
||||||
@version 9.2
|
@version 9.3
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
**/
|
**/
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local today now;
|
%local today now;
|
||||||
%let today=%sysfunc(today(),yymmddn8.);
|
%let today=%sysfunc(today(),yymmddn8.);
|
||||||
%let now=%sysfunc(compress(%sysfunc(time(),time12.3),:.));
|
%let now=%sysfunc(compress(%sysfunc(time(),tod12.3),:.));
|
||||||
|
|
||||||
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
|
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
|
||||||
|
|
||||||
|
|||||||
92
meta/mm_deletelibrary.sas
Normal file
92
meta/mm_deletelibrary.sas
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Deletes a library by Name
|
||||||
|
|
||||||
|
@details Used to delete a library.
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%* create a library in the home directory ;
|
||||||
|
%mm_createlibrary(
|
||||||
|
libname=My Temp Library,
|
||||||
|
libref=XXTEMPXX,
|
||||||
|
tree=/User Folders/&sysuserid,
|
||||||
|
directory=%sysfunc(pathname(work))
|
||||||
|
)
|
||||||
|
|
||||||
|
%* delete the library ;
|
||||||
|
%mm_deletelibrary(name=My Temp Library)
|
||||||
|
|
||||||
|
After running the above, the following will be shown in the log:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
@param [in] name= the name (not libref) of the library to be deleted
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
|
||||||
|
@version 9.4
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mm_deletelibrary(
|
||||||
|
name=
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if library exists and get uri
|
||||||
|
*/
|
||||||
|
data _null_;
|
||||||
|
length type uri $256;
|
||||||
|
rc=metadata_resolve("omsobj:SASLibrary?@Name='&name'",type,uri);
|
||||||
|
call symputx('checktype',type,'l');
|
||||||
|
call symputx('liburi',uri,'l');
|
||||||
|
putlog (_all_)(=);
|
||||||
|
run;
|
||||||
|
%if &checktype ne SASLibrary %then %do;
|
||||||
|
%put &sysmacroname: Library (&name) was not found, and so will not be deleted;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%local fname1 fname2;
|
||||||
|
%let fname1=%mf_getuniquefileref();
|
||||||
|
%let fname2=%mf_getuniquefileref();
|
||||||
|
|
||||||
|
filename &fname1 temp lrecl=10000;
|
||||||
|
filename &fname2 temp lrecl=10000;
|
||||||
|
data _null_ ;
|
||||||
|
file &fname1 ;
|
||||||
|
put "<DeleteMetadata><Metadata><SASLibrary Id='&liburi'/>";
|
||||||
|
put "</Metadata><NS>SAS</NS><Flags>268436480</Flags><Options/>";
|
||||||
|
put "</DeleteMetadata>";
|
||||||
|
run ;
|
||||||
|
proc metadata in=&fname1 out=&fname2 verbose;run;
|
||||||
|
|
||||||
|
/* list the result */
|
||||||
|
data _null_;infile &fname2; input; list; run;
|
||||||
|
|
||||||
|
filename &fname1 clear;
|
||||||
|
filename &fname2 clear;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check deletion
|
||||||
|
*/
|
||||||
|
%local isgone;
|
||||||
|
data _null_;
|
||||||
|
length type uri $256;
|
||||||
|
rc=metadata_resolve("omsobj:SASLibrary?@Id='&liburi'",type,uri);
|
||||||
|
call symputx('isgone',type,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&isgone = SASLibrary)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Library (&name) NOT deleted)
|
||||||
|
)
|
||||||
|
|
||||||
|
%put &sysmacroname: Library &name (&liburi) was successfully deleted;
|
||||||
|
|
||||||
|
%mend;
|
||||||
24
package-lock.json
generated
24
package-lock.json
generated
@@ -7,7 +7,29 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "@sasjs/core",
|
"name": "@sasjs/core",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT"
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-git-hooks": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-git-hooks": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-git-hooks/-/node-git-hooks-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-05rULsJy8z2OvXTQFZv9fN20uo186EYgJYQjkL1OjnXj53QivOAGUzZilZ/MX8OmPRaN+deJBtlvMRydpdfnqA==",
|
||||||
|
"bin": {
|
||||||
|
"node-git-hooks": "bin/install.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-git-hooks": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-git-hooks/-/node-git-hooks-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-05rULsJy8z2OvXTQFZv9fN20uo186EYgJYQjkL1OjnXj53QivOAGUzZilZ/MX8OmPRaN+deJBtlvMRydpdfnqA=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@sasjs/core",
|
"name": "@sasjs/core",
|
||||||
"description": "SAS Macro Library for Application Development",
|
"description": "Production Ready Macros for SAS Application Developers",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"SAS",
|
"SAS",
|
||||||
@@ -28,6 +28,10 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"docs": "sasjs doc && ./sasjs/utils/build.sh"
|
"docs": "sasjs doc && ./sasjs/utils/build.sh",
|
||||||
|
"postinstall": "node-git-hooks"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-git-hooks": "^1.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,20 +14,20 @@ HIDE_SCOPE_NAMES = YES
|
|||||||
HIDE_UNDOC_CLASSES = YES
|
HIDE_UNDOC_CLASSES = YES
|
||||||
HIDE_UNDOC_MEMBERS = YES
|
HIDE_UNDOC_MEMBERS = YES
|
||||||
HTML_OUTPUT = $(DOXY_HTML_OUTPUT)
|
HTML_OUTPUT = $(DOXY_HTML_OUTPUT)
|
||||||
HTML_HEADER = $(DOXY_CONTENT)new_header.html
|
HTML_HEADER = $(HTML_HEADER)
|
||||||
HTML_FOOTER = $(DOXY_CONTENT)new_footer.html
|
HTML_EXTRA_FILES = $(HTML_EXTRA_FILES)
|
||||||
HTML_EXTRA_STYLESHEET = $(DOXY_CONTENT)new_stylesheet.css
|
HTML_FOOTER = $(HTML_FOOTER)
|
||||||
|
HTML_EXTRA_STYLESHEET = $(HTML_EXTRA_STYLESHEET)
|
||||||
INHERIT_DOCS = NO
|
INHERIT_DOCS = NO
|
||||||
INLINE_INFO = NO
|
INLINE_INFO = NO
|
||||||
INPUT = $(DOXY_CONTENT)../../README.md \
|
INPUT = $(DOXY_INPUT)
|
||||||
= $(DOXY_CONTENT)../../main.dox \
|
INPUT += main.dox
|
||||||
$(DOXY_INPUT)
|
LAYOUT_FILE = $(LAYOUT_FILE)
|
||||||
USE_MDFILE_AS_MAINPAGE = README.md
|
USE_MDFILE_AS_MAINPAGE = README.md
|
||||||
LAYOUT_FILE = $(DOXY_CONTENT)DoxygenLayout.xml
|
|
||||||
MAX_INITIALIZER_LINES = 0
|
MAX_INITIALIZER_LINES = 0
|
||||||
PROJECT_NAME = Macro Core
|
PROJECT_NAME = $(PROJECT_NAME)
|
||||||
PROJECT_LOGO = $(DOXY_CONTENT)Macro_core_website_1.png
|
PROJECT_LOGO = $(PROJECT_LOGO)
|
||||||
PROJECT_BRIEF = "Production Ready Macros for SAS Application Developers"
|
PROJECT_BRIEF = $(PROJECT_BRIEF)
|
||||||
RECURSIVE = YES
|
RECURSIVE = YES
|
||||||
REPEAT_BRIEF = NO
|
REPEAT_BRIEF = NO
|
||||||
SHOW_NAMESPACES = NO
|
SHOW_NAMESPACES = NO
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
ECHO on
|
|
||||||
|
|
||||||
rmdir /s /q C:\DEVELOPMENT\output
|
|
||||||
mkdir C:\DEVELOPMENT\output
|
|
||||||
|
|
||||||
doxygen.exe Doxyfile
|
|
||||||
26
sasjs/doxy/doxygen.svg
Normal file
26
sasjs/doxy/doxygen.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
sasjs/doxy/logo.png
Normal file
BIN
sasjs/doxy/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
@@ -8,7 +8,7 @@
|
|||||||
<li class="footer">
|
<li class="footer">
|
||||||
$generatedby
|
$generatedby
|
||||||
<a href="https://www.doxygen.org/index.html">
|
<a href="https://www.doxygen.org/index.html">
|
||||||
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"
|
<img class="footer" src="$relpath^doxygen.svg" alt="doxygen"
|
||||||
/></a>
|
/></a>
|
||||||
$doxygenversion
|
$doxygenversion
|
||||||
</li>
|
</li>
|
||||||
@@ -24,9 +24,10 @@
|
|||||||
<address class="footer">
|
<address class="footer">
|
||||||
<small>
|
<small>
|
||||||
$generatedby  <a href="http://www.doxygen.org/index.html">
|
$generatedby  <a href="http://www.doxygen.org/index.html">
|
||||||
<img class="footer" src="$relpath^doxygen.png" alt="doxygen" />
|
<img class="footer" src="$relpath^doxygen.svg" alt="doxygen" />
|
||||||
</a>
|
</a>
|
||||||
$doxygenversion
|
$doxygenversion
|
||||||
</small>
|
</small>
|
||||||
</address>
|
</address>
|
||||||
|
|
||||||
<!--END !GENERATE_TREEVIEW-->
|
<!--END !GENERATE_TREEVIEW-->
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<meta name="generator" content="Doxygen $doxygenversion" />
|
<meta name="generator" content="Doxygen $doxygenversion" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<!--BEGIN PROJECT_NAME-->
|
<!--BEGIN PROJECT_NAME-->
|
||||||
<title>$projectname: $title</title>
|
<meta name="description" content="$projectbrief" />
|
||||||
<!--END PROJECT_NAME-->
|
<!--END PROJECT_NAME-->
|
||||||
<!--BEGIN !PROJECT_NAME-->
|
<!--BEGIN !PROJECT_NAME-->
|
||||||
<title>$title</title>
|
<title>$title</title>
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||||
$treeview $search $mathjax
|
$treeview $search $mathjax
|
||||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||||
<link rel="icon" href="https://sasjs.io/img/runningman.jpg" />
|
<link rel="shortcut icon" href="$relpath^favicon.ico" type="image/x-icon" />
|
||||||
$extrastylesheet
|
$extrastylesheet
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -33,52 +33,24 @@
|
|||||||
<tr style="height: 56px">
|
<tr style="height: 56px">
|
||||||
<!--BEGIN PROJECT_LOGO-->
|
<!--BEGIN PROJECT_LOGO-->
|
||||||
<td id="projectlogo">
|
<td id="projectlogo">
|
||||||
<img alt="Logo" src="$relpath^$projectlogo" />
|
<a href="$relpath^"
|
||||||
|
><img alt="Logo" src="$relpath^$projectlogo"
|
||||||
|
/></a>
|
||||||
</td>
|
</td>
|
||||||
<!--END PROJECT_LOGO-->
|
<!--END PROJECT_LOGO-->
|
||||||
<!--BEGIN PROJECT_NAME-->
|
|
||||||
<td id="projectalign" style="padding-left: 0.5em">
|
<td id="projectalign" style="padding-left: 0.5em">
|
||||||
<div id="projectname">
|
|
||||||
<!--BEGIN PROJECT_NUMBER--> <span id="projectnumber"
|
|
||||||
>$projectnumber</span
|
|
||||||
><!--END PROJECT_NUMBER-->
|
|
||||||
</div>
|
|
||||||
<!--BEGIN PROJECT_BRIEF-->
|
|
||||||
<div id="projectbrief">
|
<div id="projectbrief">
|
||||||
Production Ready Macros for SAS Application Developers<br />
|
Production Ready Macros for SAS Application Developers<br />
|
||||||
<a href="https://github.com/sasjs/core">
|
<a href="https://github.com/sasjs/core">
|
||||||
https://github.com/sasjs/core
|
https://github.com/sasjs/core
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<meta name="Description" content="$projectbrief" />
|
|
||||||
<!--END PROJECT_BRIEF-->
|
|
||||||
</td>
|
|
||||||
<!--END PROJECT_NAME-->
|
|
||||||
<!--BEGIN !PROJECT_NAME-->
|
|
||||||
<!--BEGIN PROJECT_BRIEF-->
|
|
||||||
<td style="padding-left: 0.5em">
|
|
||||||
<div id="projectbrief">$projectbrief</div>
|
|
||||||
<table
|
|
||||||
style="padding-left: 2em"
|
|
||||||
cellspacing="0"
|
|
||||||
cellpadding="0"
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Production Ready Macros for SAS Application Developers
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="https://github.com/sasjs/core">
|
|
||||||
https://github.com/sasjs/core
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
<!--END PROJECT_BRIEF-->
|
|
||||||
<!--END !PROJECT_NAME-->
|
|
||||||
<!--BEGIN DISABLE_INDEX-->
|
<!--BEGIN DISABLE_INDEX-->
|
||||||
<!--BEGIN SEARCHENGINE-->
|
<!--BEGIN SEARCHENGINE-->
|
||||||
<td>$searchbox</td>
|
<td>$searchbox</td>
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
"$schema": "https://cli.sasjs.io/sasjsconfig-schema.json",
|
"$schema": "https://cli.sasjs.io/sasjsconfig-schema.json",
|
||||||
"macroFolders": ["base", "meta", "metax", "viya", "lua"],
|
"macroFolders": ["base", "meta", "metax", "viya", "lua"],
|
||||||
"docConfig":{
|
"docConfig":{
|
||||||
"displayMacroCore": false
|
"displayMacroCore": false,
|
||||||
|
"enableLineage": false,
|
||||||
|
"doxyContent": {
|
||||||
|
"favIcon": "runningman.jpg",
|
||||||
|
"logo": "Macro_core_website_1.png",
|
||||||
|
"readMe": "../../README.md"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user