mirror of
https://github.com/sasjs/core.git
synced 2026-01-05 00:20:05 +00:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
412182a022 | ||
|
|
43b8ee1c7e | ||
|
|
83eea02240 | ||
|
|
a14e31804a | ||
|
|
3fa639ebf7 | ||
|
|
ed11d44fe8 | ||
|
|
de4ea8888f | ||
|
|
ea0a936871 | ||
|
|
042987c91e | ||
|
|
6669e74baa | ||
|
|
906f9a139d | ||
|
|
b31f960635 | ||
|
|
1ed3cb31b5 | ||
|
|
ca7c332f20 | ||
|
|
d587b44b34 | ||
|
|
e43aac972a | ||
|
|
7dbe31b5d3 | ||
|
|
1672c96340 | ||
|
|
453aee2c1f | ||
|
|
00abbdcd65 | ||
|
|
88685dc585 | ||
|
|
cf8147d6ca | ||
|
|
f28f6b1530 | ||
|
|
cb4ea71e81 | ||
|
|
fe94d3781a | ||
|
|
7c17b39dad | ||
|
|
73dab4c651 | ||
|
|
5d72843167 | ||
|
|
f43df47cff | ||
|
|
aaca26770b | ||
|
|
4a124d5bd8 | ||
|
|
03cd52a01a | ||
|
|
da79181b00 | ||
|
|
a405104052 | ||
|
|
56fdaa65d2 | ||
|
|
9d60c49c9f | ||
|
|
380170d5ba | ||
|
|
4b450f2091 | ||
|
|
1b013fbf1c | ||
|
|
bf7459bd2d | ||
|
|
1096db0846 | ||
|
|
fc9b765246 | ||
|
|
4a8f7bb014 | ||
|
|
e0469be0d8 | ||
|
|
e9e576b5ec |
@@ -126,6 +126,15 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "eltociear",
|
||||||
|
"name": "Ikko Ashimine",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/22633385?v=4",
|
||||||
|
"profile": "https://bandism.net/",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|||||||
8
.devcontainer/Dockerfile
Normal file
8
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.233.0/containers/javascript-node/.devcontainer/base.Dockerfile
|
||||||
|
|
||||||
|
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
|
||||||
|
ARG VARIANT="18-bullseye"
|
||||||
|
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y doxygen
|
||||||
26
.devcontainer/devcontainer.json
Normal file
26
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.233.0/containers/typescript-node
|
||||||
|
{
|
||||||
|
"name": "Node.js & TypeScript",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
// Update 'VARIANT' to pick a Node version: 18, 16, 14.
|
||||||
|
// Append -bullseye or -buster to pin to an OS version.
|
||||||
|
// Use -bullseye variants on local on arm64/Apple Silicon.
|
||||||
|
"args": {
|
||||||
|
"VARIANT": "16-bullseye"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {},
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": [
|
||||||
|
"SASjs.sasjs-for-vscode"
|
||||||
|
],
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
"postCreateCommand": "npm i && npm i -g @sasjs/cli",
|
||||||
|
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
|
"remoteUser": "node"
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ sasjs/
|
|||||||
.github/
|
.github/
|
||||||
.git-hooks/
|
.git-hooks/
|
||||||
.vscode/
|
.vscode/
|
||||||
main.dox
|
|
||||||
make_singlefile.sh
|
make_singlefile.sh
|
||||||
*.md
|
*.md
|
||||||
.all-contributorsrc
|
.all-contributorsrc
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
[dependency-url]:https://github.com/sasjs/core/blob/main/package.json
|
[dependency-url]:https://github.com/sasjs/core/blob/main/package.json
|
||||||
|
|
||||||
|
|
||||||
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.
|
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/.github/CONTRIBUTING.md) are welcome.
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
@@ -224,12 +224,13 @@ The following repositories are also worth checking out:
|
|||||||
* [chris-swenson/sasmacros](https://github.com/chris-swenson/sasmacros)
|
* [chris-swenson/sasmacros](https://github.com/chris-swenson/sasmacros)
|
||||||
* [greg-wotton/sas-programs](https://github.com/greg-wootton/sas-programs)
|
* [greg-wotton/sas-programs](https://github.com/greg-wootton/sas-programs)
|
||||||
* [KatjaGlassConsulting/SMILE-SmartSASMacros](https://github.com/KatjaGlassConsulting/SMILE-SmartSASMacros)
|
* [KatjaGlassConsulting/SMILE-SmartSASMacros](https://github.com/KatjaGlassConsulting/SMILE-SmartSASMacros)
|
||||||
|
* [rogerjdeangelis](https://github.com/rogerjdeangelis)
|
||||||
* [scottbass/sas](https://github.com/scottbass/SAS)
|
* [scottbass/sas](https://github.com/scottbass/SAS)
|
||||||
* [yabwon/sas_packages](https://github.com/yabwon/SAS_PACKAGES)
|
* [yabwon/sas_packages](https://github.com/yabwon/SAS_PACKAGES)
|
||||||
|
|
||||||
## Contributors ✨
|
## Contributors ✨
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||||
[](#contributors-)
|
[](#contributors-)
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||||
|
|
||||||
@@ -251,6 +252,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<td align="center"><a href="https://github.com/VladislavParhomchik"><img src="https://avatars.githubusercontent.com/u/83717836?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vladislav Parhomchik</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=VladislavParhomchik" title="Tests">⚠️</a> <a href="https://github.com/sasjs/core/pulls?q=is%3Apr+reviewed-by%3AVladislavParhomchik" title="Reviewed Pull Requests">👀</a></td>
|
<td align="center"><a href="https://github.com/VladislavParhomchik"><img src="https://avatars.githubusercontent.com/u/83717836?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vladislav Parhomchik</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=VladislavParhomchik" title="Tests">⚠️</a> <a href="https://github.com/sasjs/core/pulls?q=is%3Apr+reviewed-by%3AVladislavParhomchik" title="Reviewed Pull Requests">👀</a></td>
|
||||||
<td align="center"><a href="https://github.com/vznesh"><img src="https://avatars.githubusercontent.com/u/28916792?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vignesh T.</b></sub></a><br /><a href="https://github.com/sasjs/core/issues?q=author%3Avznesh" title="Bug reports">🐛</a></td>
|
<td align="center"><a href="https://github.com/vznesh"><img src="https://avatars.githubusercontent.com/u/28916792?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vignesh T.</b></sub></a><br /><a href="https://github.com/sasjs/core/issues?q=author%3Avznesh" title="Bug reports">🐛</a></td>
|
||||||
<td align="center"><a href="https://github.com/yabwon"><img src="https://avatars.githubusercontent.com/u/9314894?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bart Jablonski</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=yabwon" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/yabwon"><img src="https://avatars.githubusercontent.com/u/9314894?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bart Jablonski</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=yabwon" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/sasjs/core/commits?author=eltociear" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
42
base/mf_fmtdttm.sas
Normal file
42
base/mf_fmtdttm.sas
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Returns E8601DT26.6 if compatible else DATETIME19.3
|
||||||
|
@details From our experience in [Data Controller for SAS]
|
||||||
|
(https://datacontroller.io) deployments, the E8601DT26.6 datetime format has
|
||||||
|
the widest support when it comes to pass-through SQL queries.
|
||||||
|
|
||||||
|
However, it is not supported in WPS or early versions of SAS 9 (M3 and below)
|
||||||
|
when used as a datetime literal, eg:
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
demo="%sysfunc(datetime(),E8601DT26.6)"dt;
|
||||||
|
demo=;
|
||||||
|
run;
|
||||||
|
|
||||||
|
This macro will therefore return DATEITME19.3 as an alternative format
|
||||||
|
based on the runtime environment so that it can be used in such cases, eg:
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
demo="%sysfunc(datetime(),%mf_fmtdttm())"dt;
|
||||||
|
demo=;
|
||||||
|
run;
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mf_fmtdttm.test.sas
|
||||||
|
|
||||||
|
@author Allan Bowe
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mf_fmtdttm(
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%if "&sysver"="9.2" or "&sysver"="9.3"
|
||||||
|
or ("&sysver"="9.4" and "%substr(&SYSVLONG,9,1)" le "3")
|
||||||
|
or "%substr(&sysver,1,1)"="4"
|
||||||
|
or "%substr(&sysver,1,1)"="5"
|
||||||
|
%then %do;DATETIME19.3%end;
|
||||||
|
%else %do;E8601DT26.6%end;
|
||||||
|
|
||||||
|
%mend mf_fmtdttm;
|
||||||
|
|
||||||
|
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
@brief Returns an unused libref
|
@brief Returns an unused libref
|
||||||
@details Use as follows:
|
@details Use as follows:
|
||||||
|
|
||||||
libname mclib0 (work);
|
libname mclib0 (work);
|
||||||
libname mclib1 (work);
|
libname mclib1 (work);
|
||||||
libname mclib2 (work);
|
libname mclib2 (work);
|
||||||
|
|
||||||
%let libref=%mf_getuniquelibref();
|
%let libref=%mf_getuniquelibref();
|
||||||
%put &=libref;
|
%put &=libref;
|
||||||
|
|
||||||
which returns:
|
which returns:
|
||||||
|
|
||||||
|
|||||||
@@ -2,31 +2,48 @@
|
|||||||
@file
|
@file
|
||||||
@brief Returns number of variables in a dataset
|
@brief Returns number of variables in a dataset
|
||||||
@details Useful to identify those renagade datasets that have no columns!
|
@details Useful to identify those renagade datasets that have no columns!
|
||||||
|
Can also be used to count for numeric, or character columns
|
||||||
|
|
||||||
%put Number of Variables=%mf_getvarcount(sashelp.class);
|
%put Number of Variables=%mf_getvarcount(sashelp.class);
|
||||||
|
%put Character Variables=%mf_getvarcount(sashelp.class,typefilter=C);
|
||||||
|
%put Numeric Variables = %mf_getvarcount(sashelp.class,typefilter=N);
|
||||||
|
|
||||||
returns:
|
returns:
|
||||||
> Number of Variables=4
|
> Number of Variables=4
|
||||||
|
|
||||||
@param libds Two part dataset (or view) reference.
|
|
||||||
|
@param [in] libds Two part dataset (or view) reference.
|
||||||
|
@param [in] typefilter= (A) Filter for certain types of column. Valid values:
|
||||||
|
@li A Count All columns
|
||||||
|
@li C Count Character columns only
|
||||||
|
@li N Count Numeric columns only
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mf_getvarcount(libds
|
%macro mf_getvarcount(libds,typefilter=A
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local dsid nvars rc ;
|
%local dsid nvars rc outcnt x;
|
||||||
%let dsid=%sysfunc(open(&libds));
|
%let dsid=%sysfunc(open(&libds));
|
||||||
%let nvars=.;
|
%let nvars=.;
|
||||||
|
%let outcnt=0;
|
||||||
|
%let typefilter=%upcase(&typefilter);
|
||||||
%if &dsid %then %do;
|
%if &dsid %then %do;
|
||||||
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
||||||
|
%if &typefilter=A %then %let outcnt=&nvars;
|
||||||
|
%else %if &nvars>0 %then %do x=1 %to &nvars;
|
||||||
|
/* increment based on variable type */
|
||||||
|
%if %sysfunc(vartype(&dsid,&x))=&typefilter %then %do;
|
||||||
|
%let outcnt=%eval(&outcnt+1);
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put unable to open &libds (rc=&dsid);
|
%put unable to open &libds (rc=&dsid);
|
||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
&nvars
|
&outcnt
|
||||||
%mend mf_getvarcount;
|
%mend mf_getvarcount;
|
||||||
@@ -89,7 +89,12 @@
|
|||||||
or "&SYSPROCESSNAME "="Compute Server "
|
or "&SYSPROCESSNAME "="Compute Server "
|
||||||
or &mode=INCLUDE
|
or &mode=INCLUDE
|
||||||
%then %do;
|
%then %do;
|
||||||
options obs=max replace nosyntaxcheck mprint;
|
options obs=max replace mprint;
|
||||||
|
%if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5"
|
||||||
|
%then %do;
|
||||||
|
options nosyntaxcheck;
|
||||||
|
%end;
|
||||||
|
|
||||||
%if &mode=INCLUDE %then %do;
|
%if &mode=INCLUDE %then %do;
|
||||||
%if %sysfunc(exist(&errds))=1 %then %do;
|
%if %sysfunc(exist(&errds))=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
%mp_copyfolder(&rootdir,©dir)
|
%mp_copyfolder(&rootdir,©dir)
|
||||||
|
|
||||||
@param source Unquoted path to the folder to copy from.
|
@param [in] source Unquoted path to the folder to copy from.
|
||||||
@param target Unquoted path to the folder to copy to.
|
@param [out] target Unquoted path to the folder to copy to.
|
||||||
|
@param [in] copymax=(MAX) Set to a positive integer to indicate the level of
|
||||||
|
subdirectory copy recursion - eg 3, to go `./3/levels/deep`. For unlimited
|
||||||
|
recursion, set to MAX.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@@ -31,7 +34,7 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mp_copyfolder(source,target);
|
%macro mp_copyfolder(source,target,copymax=MAX);
|
||||||
|
|
||||||
%mp_abort(iftrue=(%mf_isdir(&source)=0)
|
%mp_abort(iftrue=(%mf_isdir(&source)=0)
|
||||||
,mac=&sysmacroname
|
,mac=&sysmacroname
|
||||||
@@ -50,7 +53,7 @@
|
|||||||
%let tempds=%mf_getuniquename();
|
%let tempds=%mf_getuniquename();
|
||||||
|
|
||||||
/* recursive directory listing */
|
/* recursive directory listing */
|
||||||
%mp_dirlist(path=&source,outds=work.&tempds, maxdepth=MAX)
|
%mp_dirlist(path=&source,outds=work.&tempds,maxdepth=©max)
|
||||||
|
|
||||||
/* create folders and copy content */
|
/* create folders and copy content */
|
||||||
data _null_;
|
data _null_;
|
||||||
@@ -78,4 +81,4 @@
|
|||||||
proc sql;
|
proc sql;
|
||||||
drop table work.&tempds;
|
drop table work.&tempds;
|
||||||
|
|
||||||
%mend mp_copyfolder;
|
%mend mp_copyfolder;
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ proc sql;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%if &libds=0 %then %do;
|
%if &libds=0 %then %do;
|
||||||
|
proc sql;
|
||||||
describe table &syslast;
|
describe table &syslast;
|
||||||
drop table &syslast;
|
drop table &syslast;
|
||||||
%end;
|
%end;
|
||||||
%mend mp_coretable;
|
%mend mp_coretable;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
%mp_ds2cards(base_ds=sashelp.class
|
%mp_ds2cards(sashelp.class
|
||||||
, tgt_ds=work.class
|
, tgt_ds=work.class
|
||||||
, cards_file= "C:\temp\class.sas"
|
, cards_file= "C:\temp\class.sas"
|
||||||
, showlog=NO
|
, showlog=NO
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
- explicity setting a unix LF
|
- explicity setting a unix LF
|
||||||
- constraints / indexes etc
|
- constraints / indexes etc
|
||||||
|
|
||||||
@param [in] base_ds= Should be two level - eg work.blah. This is the table
|
@param [in] base_ds Should be two level - eg work.blah. This is the table
|
||||||
that is converted to a cards file.
|
that is converted to a cards file.
|
||||||
@param [in] tgt_ds= Table that the generated cards file would create.
|
@param [in] tgt_ds= Table that the generated cards file would create.
|
||||||
Optional - if omitted, will be same as BASE_DS.
|
Optional - if omitted, will be same as BASE_DS.
|
||||||
|
|||||||
@@ -57,6 +57,11 @@
|
|||||||
%local vars;
|
%local vars;
|
||||||
%let vars=%upcase(%mf_getvarlist(&libds));
|
%let vars=%upcase(%mf_getvarlist(&libds));
|
||||||
|
|
||||||
|
%if %trim(X&vars)=X %then %do;
|
||||||
|
%put &sysmacroname: Table &libds has no columns!!;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
/* create the header row */
|
/* create the header row */
|
||||||
data _null_;
|
data _null_;
|
||||||
file &outref;
|
file &outref;
|
||||||
|
|||||||
@@ -92,7 +92,36 @@ data &outds;
|
|||||||
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
|
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
|
||||||
OPERATOR_NM $10 RAW_VALUE $4000;*/
|
OPERATOR_NM $10 RAW_VALUE $4000;*/
|
||||||
set &inds;
|
set &inds;
|
||||||
length reason_cd $4032;
|
length reason_cd $4032 vtype $1 vnum dsid 8;
|
||||||
|
|
||||||
|
/* quick check to ensure column exists */
|
||||||
|
if upcase(VARIABLE_NM) not in
|
||||||
|
(%upcase(%mf_getvarlist(&targetds,dlm=%str(,),quote=SINGLE)))
|
||||||
|
then do;
|
||||||
|
REASON_CD="Variable "!!cats(variable_nm)!!" not in &targetds";
|
||||||
|
putlog REASON_CD= VARIABLE_NM=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
|
output;
|
||||||
|
return;
|
||||||
|
end;
|
||||||
|
|
||||||
|
/* need to open the dataset to get the column type */
|
||||||
|
dsid=open("&targetds","i");
|
||||||
|
if dsid>0 then do;
|
||||||
|
vnum=varnum(dsid,VARIABLE_NM);
|
||||||
|
if vnum<1 then do;
|
||||||
|
/* should not happen as was also tested for above */
|
||||||
|
REASON_CD=cats("Variable (",VARIABLE_NM,") not found in &targetds");
|
||||||
|
putlog REASON_CD= dsid=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
|
output;
|
||||||
|
return;
|
||||||
|
end;
|
||||||
|
/* now we can get the type */
|
||||||
|
else vtype=vartype(dsid,vnum);
|
||||||
|
end;
|
||||||
|
|
||||||
/* closed list checks */
|
/* closed list checks */
|
||||||
if GROUP_LOGIC not in ('AND','OR') then do;
|
if GROUP_LOGIC not in ('AND','OR') then do;
|
||||||
@@ -116,17 +145,8 @@ data &outds;
|
|||||||
call symputx('nobs',_n_,'l');
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
if upcase(VARIABLE_NM) not in
|
|
||||||
(%upcase(%mf_getvarlist(&targetds,dlm=%str(,),quote=SINGLE)))
|
|
||||||
then do;
|
|
||||||
REASON_CD="Variable "!!cats(variable_nm)!!" not in &targetds";
|
|
||||||
putlog REASON_CD= VARIABLE_NM=;
|
|
||||||
call symputx('reason_cd',reason_cd,'l');
|
|
||||||
call symputx('nobs',_n_,'l');
|
|
||||||
output;
|
|
||||||
end;
|
|
||||||
if OPERATOR_NM not in
|
if OPERATOR_NM not in
|
||||||
('=','>','<','<=','>=','BETWEEN','IN','NOT IN','NE','CONTAINS','GE','LE')
|
('=','>','<','<=','>=','NE','GE','LE','BETWEEN','IN','NOT IN','CONTAINS')
|
||||||
then do;
|
then do;
|
||||||
REASON_CD='Invalid OPERATOR_NM: '!!cats(OPERATOR_NM);
|
REASON_CD='Invalid OPERATOR_NM: '!!cats(OPERATOR_NM);
|
||||||
putlog REASON_CD= OPERATOR_NM=;
|
putlog REASON_CD= OPERATOR_NM=;
|
||||||
@@ -135,6 +155,18 @@ data &outds;
|
|||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
/* special missing logic */
|
||||||
|
if vtype='N'
|
||||||
|
and OPERATOR_NM in ('=','>','<','<=','>=','NE','GE','LE')
|
||||||
|
and cats(upcase(raw_value)) in (
|
||||||
|
'.','.A','.B','.C','.D','.E','.F','.G','.H','.I','.J','.K','.L','.M','.N'
|
||||||
|
'.N','.O','.P','.Q','.R','.S','.T','.U','.V','.W','.X','.Y','.Z','._'
|
||||||
|
)
|
||||||
|
then do;
|
||||||
|
/* valid numeric - exit data step loop */
|
||||||
|
return;
|
||||||
|
end;
|
||||||
|
|
||||||
/* special logic */
|
/* special logic */
|
||||||
if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ','');
|
if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ','');
|
||||||
else if OPERATOR_NM in ('IN','NOT IN') then do;
|
else if OPERATOR_NM in ('IN','NOT IN') then do;
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ filename &outref temp;
|
|||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
|
proc sort data=&inds;
|
||||||
|
by SUBGROUP_ID;
|
||||||
|
run;
|
||||||
data _null_;
|
data _null_;
|
||||||
file &outref lrecl=32800;
|
file &outref lrecl=32800;
|
||||||
set &inds end=last;
|
set &inds end=last;
|
||||||
|
|||||||
@@ -40,6 +40,22 @@
|
|||||||
%let lib=%upcase(&lib);
|
%let lib=%upcase(&lib);
|
||||||
%let ds=%upcase(&ds);
|
%let ds=%upcase(&ds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cater for environments where sashelp.vcncolu is not available
|
||||||
|
*/
|
||||||
|
%if %sysfunc(exist(sashelp.vcncolu,view))=0 %then %do;
|
||||||
|
proc sql;
|
||||||
|
create table &outds(
|
||||||
|
libref char(8)
|
||||||
|
,TABLE_NAME char(32)
|
||||||
|
,constraint_type char(8) label='Constraint Type'
|
||||||
|
,constraint_name char(32) label='Constraint Name'
|
||||||
|
,column_name char(32) label='Column'
|
||||||
|
,constraint_order num
|
||||||
|
);
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Neither dictionary tables nor sashelp provides a constraint order column,
|
* Neither dictionary tables nor sashelp provides a constraint order column,
|
||||||
* however they DO arrive in the correct order. So, create the col.
|
* however they DO arrive in the correct order. So, create the col.
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mcf_length.sas
|
@li mcf_length.sas
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
|
@li mf_getvarcount.sas
|
||||||
@li mf_getvarlist.sas
|
@li mf_getvarlist.sas
|
||||||
@li mf_getvartype.sas
|
@li mf_getvartype.sas
|
||||||
@li mf_getvarformat.sas
|
@li mf_getvarformat.sas
|
||||||
@@ -60,7 +61,7 @@
|
|||||||
,outds=work.mp_getmaxvarlengths
|
,outds=work.mp_getmaxvarlengths
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%local vars prefix x var fmt;
|
%local vars prefix x var fmt srcds;
|
||||||
%let vars=%mf_getvarlist(libds=&libds);
|
%let vars=%mf_getvarlist(libds=&libds);
|
||||||
%let prefix=%substr(%mf_getuniquename(),1,25);
|
%let prefix=%substr(%mf_getuniquename(),1,25);
|
||||||
%let num2char=%upcase(&num2char);
|
%let num2char=%upcase(&num2char);
|
||||||
@@ -70,6 +71,24 @@
|
|||||||
%mcf_length(wrap=YES, insert_cmplib=YES)
|
%mcf_length(wrap=YES, insert_cmplib=YES)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%if &num2char=NO
|
||||||
|
and ("%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5")
|
||||||
|
and %mf_getvarcount(&libds,typefilter=N) gt 0
|
||||||
|
%then %do;
|
||||||
|
/* custom functions not supported in summary operations */
|
||||||
|
%let srcds=%mf_getuniquename();
|
||||||
|
data &srcds/view=&srcds;
|
||||||
|
set &libds;
|
||||||
|
%do x=1 %to %sysfunc(countw(&vars,%str( )));
|
||||||
|
%let var=%scan(&vars,&x);
|
||||||
|
%if %mf_getvartype(&libds,&var)=N %then %do;
|
||||||
|
&prefix.&x=mcf_length(&var);
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
%else %let srcds=&libds;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &outds (rename=(
|
create table &outds (rename=(
|
||||||
%do x=1 %to %sysfunc(countw(&vars,%str( )));
|
%do x=1 %to %sysfunc(countw(&vars,%str( )));
|
||||||
@@ -94,10 +113,15 @@ create table &outds (rename=(
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
max(mcf_length(&var)) as &prefix.&x
|
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then %do;
|
||||||
|
max(&prefix.&x) as &prefix.&x
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
max(mcf_length(&var)) as &prefix.&x
|
||||||
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
from &libds;
|
from &srcds;
|
||||||
|
|
||||||
proc transpose data=&outds
|
proc transpose data=&outds
|
||||||
out=&outds(rename=(_name_=NAME COL1=MAXLEN));
|
out=&outds(rename=(_name_=NAME COL1=MAXLEN));
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
||||||
data &outds;
|
data &outds;
|
||||||
length hashkey $32;
|
length hashkey $32;
|
||||||
retain hashkey "%sysfunc(md5(%str(&salt)),$hex32.)";
|
hashkey=put(md5("&salt"),$hex32.);
|
||||||
output;
|
output;
|
||||||
stop;
|
stop;
|
||||||
run;
|
run;
|
||||||
@@ -69,9 +69,14 @@
|
|||||||
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
data &outds(rename=(&keyvar=hashkey) keep=&keyvar)/nonote2err;
|
data &outds(rename=(&keyvar=hashkey) keep=&keyvar)
|
||||||
|
%if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do;
|
||||||
|
/nonote2err
|
||||||
|
%end;
|
||||||
|
;
|
||||||
length &prevkeyvar &keyvar $32;
|
length &prevkeyvar &keyvar $32;
|
||||||
retain &prevkeyvar "%sysfunc(md5(%str(&salt)),$hex32.)";
|
retain &prevkeyvar;
|
||||||
|
if _n_=1 then &prevkeyvar=put(md5("&salt"),$hex32.);
|
||||||
set &libds end=&lastvar;
|
set &libds end=&lastvar;
|
||||||
/* hash should include previous row */
|
/* hash should include previous row */
|
||||||
&keyvar=%mp_md5(
|
&keyvar=%mp_md5(
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
@param [in] loop_secs= (1) Seconds to wait between each lock attempt
|
@param [in] loop_secs= (1) Seconds to wait between each lock attempt
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_fmtdttm.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
@li mp_lockfilecheck.sas
|
@li mp_lockfilecheck.sas
|
||||||
@li mf_getuser.sas
|
@li mf_getuser.sas
|
||||||
@@ -111,7 +112,7 @@ run;
|
|||||||
LOCK_LIB ="&lib";
|
LOCK_LIB ="&lib";
|
||||||
LOCK_DS="&ds";
|
LOCK_DS="&ds";
|
||||||
LOCK_STATUS_CD='LOCKED';
|
LOCK_STATUS_CD='LOCKED';
|
||||||
LOCK_START_DTTM="%sysfunc(datetime(),E8601DT26.6)"dt;
|
LOCK_START_DTTM="%sysfunc(datetime(),%mf_fmtdttm())"dt;
|
||||||
LOCK_USER_NM="&user";
|
LOCK_USER_NM="&user";
|
||||||
LOCK_PID="&sysjobid";
|
LOCK_PID="&sysjobid";
|
||||||
LOCK_REF="&ref";
|
LOCK_REF="&ref";
|
||||||
@@ -131,7 +132,7 @@ run;
|
|||||||
proc sql;
|
proc sql;
|
||||||
update &ctl_ds
|
update &ctl_ds
|
||||||
set LOCK_STATUS_CD='LOCKED'
|
set LOCK_STATUS_CD='LOCKED'
|
||||||
, LOCK_START_DTTM="%sysfunc(datetime(),E8601DT26.6)"dt
|
, LOCK_START_DTTM="%sysfunc(datetime(),%mf_fmtdttm())"dt
|
||||||
, LOCK_USER_NM="&user"
|
, LOCK_USER_NM="&user"
|
||||||
, LOCK_PID="&sysjobid"
|
, LOCK_PID="&sysjobid"
|
||||||
, LOCK_REF="&ref"
|
, LOCK_REF="&ref"
|
||||||
@@ -206,7 +207,7 @@ run;
|
|||||||
proc sql;
|
proc sql;
|
||||||
update &ctl_ds
|
update &ctl_ds
|
||||||
set LOCK_STATUS_CD='UNLOCKED'
|
set LOCK_STATUS_CD='UNLOCKED'
|
||||||
, LOCK_END_DTTM="%sysfunc(datetime(),E8601DT26.6)"dt
|
, LOCK_END_DTTM="%sysfunc(datetime(),%mf_fmtdttm())"dt
|
||||||
, LOCK_USER_NM="&user"
|
, LOCK_USER_NM="&user"
|
||||||
, LOCK_PID="&sysjobid"
|
, LOCK_PID="&sysjobid"
|
||||||
, LOCK_REF="&ref"
|
, LOCK_REF="&ref"
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_existvar.sas
|
@li mf_existvar.sas
|
||||||
|
@li mf_fmtdttm.sas
|
||||||
@li mf_getquotedstr.sas
|
@li mf_getquotedstr.sas
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@@ -217,12 +218,12 @@ quit;
|
|||||||
set keytable="&base_libds"
|
set keytable="&base_libds"
|
||||||
,keycolumn="&retained_key"
|
,keycolumn="&retained_key"
|
||||||
,max_key=%eval(&maxkey+&newkey_cnt)
|
,max_key=%eval(&maxkey+&newkey_cnt)
|
||||||
,processed_dttm="%sysfunc(datetime(),E8601DT26.6)"dt;
|
,processed_dttm="%sysfunc(datetime(),%mf_fmtdttm())"dt;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
update &maxkeytable
|
update &maxkeytable
|
||||||
set max_key=%eval(&maxkey+&newkey_cnt)
|
set max_key=%eval(&maxkey+&newkey_cnt)
|
||||||
,processed_dttm="%sysfunc(datetime(),E8601DT26.6)"dt
|
,processed_dttm="%sysfunc(datetime(),%mf_fmtdttm())"dt
|
||||||
where keytable="&base_libds";
|
where keytable="&base_libds";
|
||||||
%end;
|
%end;
|
||||||
%mp_lockanytable(UNLOCK
|
%mp_lockanytable(UNLOCK
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
data &ds1;
|
data &ds1;
|
||||||
set &dslist indsname=&inds_auto;
|
set &dslist indsname=&inds_auto;
|
||||||
&hashkey=put(md5(catx('|',%mf_getquotedstr(&key,quote=N))),$hex32.);
|
&hashkey=put(md5(catx('|',%mf_getquotedstr(&key,quote=N))),$hex32.);
|
||||||
&inds_keep=&inds_auto;
|
&inds_keep=upcase(&inds_auto);
|
||||||
proc sort;
|
proc sort;
|
||||||
by &inds_keep &hashkey;
|
by &inds_keep &hashkey;
|
||||||
run;
|
run;
|
||||||
@@ -160,8 +160,8 @@ data &ds4;
|
|||||||
tgtvar_nm=upcase(tgtvar_nm);
|
tgtvar_nm=upcase(tgtvar_nm);
|
||||||
if tgtvar_nm in (%upcase(&vlist));
|
if tgtvar_nm in (%upcase(&vlist));
|
||||||
|
|
||||||
if &inds_auto="&ds2" then tgtvar_type='N';
|
if upcase(&inds_auto)="&ds2" then tgtvar_type='N';
|
||||||
else if &inds_auto="&ds3" then tgtvar_type='C';
|
else if upcase(&inds_auto)="&ds3" then tgtvar_type='C';
|
||||||
else do;
|
else do;
|
||||||
putlog "%str(ERR)OR: unidentified vartype input!" &inds_auto;
|
putlog "%str(ERR)OR: unidentified vartype input!" &inds_auto;
|
||||||
call symputx('syscc',98);
|
call symputx('syscc',98);
|
||||||
|
|||||||
@@ -26,9 +26,19 @@
|
|||||||
oldval_num num format=best32. label='Old (numeric) value',
|
oldval_num num format=best32. label='Old (numeric) value',
|
||||||
newval_num num format=best32. label='New (numeric) value',
|
newval_num num format=best32. label='New (numeric) value',
|
||||||
oldval_char char(32765) label='Old (character) value',
|
oldval_char char(32765) label='Old (character) value',
|
||||||
newval_char char(32765) label='New (character) value',
|
newval_char char(32765) label='New (character) value'
|
||||||
constraint pk_mpe_audit
|
|
||||||
primary key(load_ref,libref,dsn,key_hash,tgtvar_nm)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
%local lib;
|
||||||
|
%let libds=%upcase(&libds);
|
||||||
|
%if %index(&libds,.)=0 %then %let lib=WORK;
|
||||||
|
%else %let lib=%scan(&libds,1,.);
|
||||||
|
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify %scan(&libds,-1,.);
|
||||||
|
index create
|
||||||
|
pk_mpe_audit=(load_ref libref dsn key_hash tgtvar_nm)
|
||||||
|
/nomiss unique;
|
||||||
|
quit;
|
||||||
|
|
||||||
%mend mddl_dc_difftable;
|
%mend mddl_dc_difftable;
|
||||||
@@ -9,19 +9,32 @@
|
|||||||
|
|
||||||
%macro mddl_dc_filterdetail(libds=WORK.FILTER_DETAIL);
|
%macro mddl_dc_filterdetail(libds=WORK.FILTER_DETAIL);
|
||||||
|
|
||||||
|
%local nn lib;
|
||||||
|
%if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do;
|
||||||
|
%let nn=not null;
|
||||||
|
%end;
|
||||||
|
%else %let nn=;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &libds(
|
create table &libds(
|
||||||
filter_hash char(32) not null,
|
filter_hash char(32) &nn,
|
||||||
filter_line num not null,
|
filter_line num &nn,
|
||||||
group_logic char(3) not null,
|
group_logic char(3) &nn,
|
||||||
subgroup_logic char(3) not null,
|
subgroup_logic char(3) &nn,
|
||||||
subgroup_id num not null,
|
subgroup_id num &nn,
|
||||||
variable_nm varchar(32) not null,
|
variable_nm varchar(32) &nn,
|
||||||
operator_nm varchar(12) not null,
|
operator_nm varchar(12) &nn,
|
||||||
raw_value varchar(4000) not null,
|
raw_value varchar(4000) &nn,
|
||||||
processed_dttm num not null format=E8601DT26.6,
|
processed_dttm num &nn format=E8601DT26.6
|
||||||
constraint pk_mpe_filteranytable
|
|
||||||
primary key(filter_hash,filter_line)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
%let libds=%upcase(&libds);
|
||||||
|
%if %index(&libds,.)=0 %then %let lib=WORK;
|
||||||
|
%else %let lib=%scan(&libds,1,.);
|
||||||
|
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify %scan(&libds,-1,.);
|
||||||
|
index create pk_mpe_filterdetail=(filter_hash filter_line)/nomiss unique;
|
||||||
|
quit;
|
||||||
|
|
||||||
%mend mddl_dc_filterdetail;
|
%mend mddl_dc_filterdetail;
|
||||||
@@ -9,14 +9,27 @@
|
|||||||
|
|
||||||
%macro mddl_dc_filtersummary(libds=WORK.FILTER_SUMMARY);
|
%macro mddl_dc_filtersummary(libds=WORK.FILTER_SUMMARY);
|
||||||
|
|
||||||
|
%local nn lib;
|
||||||
|
%if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do;
|
||||||
|
%let nn=not null;
|
||||||
|
%end;
|
||||||
|
%else %let nn=;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &libds(
|
create table &libds(
|
||||||
filter_rk num not null,
|
filter_rk num &nn,
|
||||||
filter_hash char(32) not null,
|
filter_hash char(32) &nn,
|
||||||
filter_table char(41) not null,
|
filter_table char(41) &nn,
|
||||||
processed_dttm num not null format=E8601DT26.6,
|
processed_dttm num &nn format=E8601DT26.6
|
||||||
constraint pk_mpe_filteranytable
|
|
||||||
primary key(filter_rk)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
%let libds=%upcase(&libds);
|
||||||
|
%if %index(&libds,.)=0 %then %let lib=WORK;
|
||||||
|
%else %let lib=%scan(&libds,1,.);
|
||||||
|
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify %scan(&libds,-1,.);
|
||||||
|
index create filter_rk /nomiss unique;
|
||||||
|
quit;
|
||||||
|
|
||||||
%mend mddl_dc_filtersummary;
|
%mend mddl_dc_filtersummary;
|
||||||
@@ -9,17 +9,33 @@
|
|||||||
|
|
||||||
%macro mddl_dc_locktable(libds=WORK.LOCKTABLE);
|
%macro mddl_dc_locktable(libds=WORK.LOCKTABLE);
|
||||||
|
|
||||||
|
%local nn lib;
|
||||||
|
%if "%substr(&sysver,1,1)" ne "4" and "%substr(&sysver,1,1)" ne "5" %then %do;
|
||||||
|
%let nn=not null;
|
||||||
|
%end;
|
||||||
|
%else %let nn=;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &libds(
|
create table &libds(
|
||||||
lock_lib char(8),
|
lock_lib char(8),
|
||||||
lock_ds char(32),
|
lock_ds char(32),
|
||||||
lock_status_cd char(10) not null,
|
lock_status_cd char(10) &nn,
|
||||||
lock_user_nm char(100) not null ,
|
lock_user_nm char(100) &nn ,
|
||||||
lock_ref char(200),
|
lock_ref char(200),
|
||||||
lock_pid char(10),
|
lock_pid char(10),
|
||||||
lock_start_dttm num format=E8601DT26.6,
|
lock_start_dttm num format=E8601DT26.6,
|
||||||
lock_end_dttm num format=E8601DT26.6,
|
lock_end_dttm num format=E8601DT26.6
|
||||||
constraint pk_mp_lockanytable primary key(lock_lib,lock_ds)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
%let libds=%upcase(&libds);
|
||||||
|
%if %index(&libds,.)=0 %then %let lib=WORK;
|
||||||
|
%else %let lib=%scan(&libds,1,.);
|
||||||
|
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify %scan(&libds,-1,.);
|
||||||
|
index create
|
||||||
|
pk_mp_lockanytable=(lock_lib lock_ds)
|
||||||
|
/nomiss unique;
|
||||||
|
quit;
|
||||||
|
|
||||||
%mend mddl_dc_locktable;
|
%mend mddl_dc_locktable;
|
||||||
@@ -17,8 +17,17 @@
|
|||||||
max_key num label=
|
max_key num label=
|
||||||
'Integer representing current max RK or SK value in the KEYTABLE',
|
'Integer representing current max RK or SK value in the KEYTABLE',
|
||||||
processed_dttm num format=E8601DT26.6
|
processed_dttm num format=E8601DT26.6
|
||||||
label='Datetime this value was last updated',
|
label='Datetime this value was last updated'
|
||||||
constraint pk_mpe_maxkeyvalues
|
);
|
||||||
primary key(keytable));
|
|
||||||
|
%local lib;
|
||||||
|
%let libds=%upcase(&libds);
|
||||||
|
%if %index(&libds,.)=0 %then %let lib=WORK;
|
||||||
|
%else %let lib=%scan(&libds,1,.);
|
||||||
|
|
||||||
|
proc datasets lib=&lib noprint;
|
||||||
|
modify %scan(&libds,-1,.);
|
||||||
|
index create keytable /nomiss unique;
|
||||||
|
quit;
|
||||||
|
|
||||||
%mend mddl_dc_maxkeytable;
|
%mend mddl_dc_maxkeytable;
|
||||||
@@ -14,8 +14,8 @@ proc sql;
|
|||||||
create table &libds(
|
create table &libds(
|
||||||
FMTNAME char(32) label='Format name'
|
FMTNAME char(32) label='Format name'
|
||||||
/*
|
/*
|
||||||
to accomodate larger START values, mp_loadformat.sas will need the
|
to accommodate larger START values, mp_loadformat.sas will need the
|
||||||
SQL dependency removed (proc sql needs to accomodate 3 index values in
|
SQL dependency removed (proc sql needs to accommodate 3 index values in
|
||||||
a 32767 ibufsize limit)
|
a 32767 ibufsize limit)
|
||||||
*/
|
*/
|
||||||
,START char(10000) label='Starting value for format'
|
,START char(10000) label='Starting value for format'
|
||||||
@@ -40,4 +40,4 @@ create table &libds(
|
|||||||
,LANGUAGE char(8) label='Language for date strings'
|
,LANGUAGE char(8) label='Language for date strings'
|
||||||
);
|
);
|
||||||
|
|
||||||
%mend mddl_sas_cntlout;
|
%mend mddl_sas_cntlout;
|
||||||
|
|||||||
11
main.dox
11
main.dox
@@ -92,4 +92,15 @@
|
|||||||
* Auto-generated from the plain source `.lua` files in the same directory
|
* Auto-generated from the plain source `.lua` files in the same directory
|
||||||
* Prefixes: _ml_
|
* Prefixes: _ml_
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \dir ddl
|
||||||
|
* \brief Data Definition Language files
|
||||||
|
* \details Provides templates for commonly used tables in sasjs/core.
|
||||||
|
Attributes:
|
||||||
|
|
||||||
|
* OS independent
|
||||||
|
* No X command
|
||||||
|
* Prefixes: _mddl_
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sas9",
|
"name": "sas9",
|
||||||
"serverUrl": "https://sas.analytium.co.uk:8343",
|
"serverUrl": "",
|
||||||
"serverType": "SAS9",
|
"serverType": "SAS9",
|
||||||
"httpsAgentOptions": {
|
"httpsAgentOptions": {
|
||||||
"allowInsecureRequests": false
|
"allowInsecureRequests": false
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "docsonly",
|
"name": "docsonly",
|
||||||
"serverType": "SAS9",
|
"serverType": "SASJS",
|
||||||
"appLoc": "dummy",
|
"appLoc": "dummy",
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
"meta",
|
"meta",
|
||||||
@@ -105,4 +105,4 @@
|
|||||||
"contextName": "SAS Job Execution compute context"
|
"contextName": "SAS Job Execution compute context"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ data _null_;
|
|||||||
file &fname1 lrecl=1000;
|
file &fname1 lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put "Content-Type: multipart/form-data; boundary=&boundary";
|
if _n_=1 then put "Content-Type: multipart/form-data; boundary=&boundary";
|
||||||
put "Authorization: Bearer " _infile_;
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
|
|||||||
149
server/ms_creategroup.sas
Normal file
149
server/ms_creategroup.sas
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Creates a group on SASjs Server
|
||||||
|
@details Creates a group on SASjs Server with the following attributes:
|
||||||
|
|
||||||
|
@li name
|
||||||
|
@li description
|
||||||
|
@li isActive
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
%ms_creategroup(mynewgroup)
|
||||||
|
|
||||||
|
%ms_creategroup(mynewergroup, desc=The group description)
|
||||||
|
|
||||||
|
@param [in] groupname The group name to create. No spaces or special chars.
|
||||||
|
@param [in] desc= (0) If no description provided, group name will be used.
|
||||||
|
@param [in] isactive= (true) Set to false to create an inactive group.
|
||||||
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
@param [out] outds= (work.ms_creategroup) This output dataset will contain the
|
||||||
|
values from the JSON response (such as the id of the new group)
|
||||||
|
|DESCRIPTION:$1.|GROUPID:best.|ISACTIVE:best.|NAME:$11.|
|
||||||
|
|---|---|---|---|
|
||||||
|
|`The group description`|`2 `|`1 `|`mynewergroup `|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquelibref.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li ms_creategroup.test.sas
|
||||||
|
@li ms_getgroups.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro ms_creategroup(groupname
|
||||||
|
,desc=0
|
||||||
|
,isactive=true
|
||||||
|
,outds=work.ms_creategroup
|
||||||
|
,mdebug=0
|
||||||
|
);
|
||||||
|
|
||||||
|
%mp_abort(
|
||||||
|
iftrue=(&syscc ne 0)
|
||||||
|
,mac=ms_creategroup.sas
|
||||||
|
,msg=%str(syscc=&syscc on macro entry)
|
||||||
|
)
|
||||||
|
|
||||||
|
%local fref0 fref1 fref2 libref optval rc msg;
|
||||||
|
%let fref0=%mf_getuniquefileref();
|
||||||
|
%let fref1=%mf_getuniquefileref();
|
||||||
|
%let fref2=%mf_getuniquefileref();
|
||||||
|
%let libref=%mf_getuniquelibref();
|
||||||
|
|
||||||
|
/* avoid sending bom marker to API */
|
||||||
|
%let optval=%sysfunc(getoption(bomfile));
|
||||||
|
options nobomfile;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &fref0 termstr=crlf;
|
||||||
|
name=quote(cats(symget('groupname')));
|
||||||
|
description=quote(cats(symget('desc')));
|
||||||
|
if cats(description)='"0"' then description=name;
|
||||||
|
isactive=symget('isactive');
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
putlog _all_;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
put '{'@;
|
||||||
|
put '"name":' name @;
|
||||||
|
put ',"description":' description @;
|
||||||
|
put ',"isActive":' isactive @;
|
||||||
|
put '}';
|
||||||
|
run;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &fref1 lrecl=1000;
|
||||||
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
|
input;
|
||||||
|
if _n_=1 then do;
|
||||||
|
put "Content-Type: application/json";
|
||||||
|
put "accept: application/json";
|
||||||
|
end;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
data _null_;
|
||||||
|
infile &fref0;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
data _null_;
|
||||||
|
infile &fref1;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
proc http method='POST' in=&fref0 headerin=&fref1 out=&fref2
|
||||||
|
url="&_sasjs_apiserverurl/SASjsApi/group";
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
debug level=1;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(
|
||||||
|
iftrue=(&syscc ne 0)
|
||||||
|
,mac=ms_creategroup.sas
|
||||||
|
,msg=%str(Issue submitting query to SASjsApi/group)
|
||||||
|
)
|
||||||
|
|
||||||
|
libname &libref JSON fileref=&fref2;
|
||||||
|
|
||||||
|
data &outds;
|
||||||
|
set &libref..root;
|
||||||
|
drop ordinal_root;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
putlog _all_;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
|
||||||
|
%mp_abort(
|
||||||
|
iftrue=(&syscc ne 0)
|
||||||
|
,mac=ms_creategroup.sas
|
||||||
|
,msg=%str(Issue reading response JSON)
|
||||||
|
)
|
||||||
|
|
||||||
|
/* reset options */
|
||||||
|
options &optval;
|
||||||
|
|
||||||
|
%if &mdebug=0 %then %do;
|
||||||
|
filename &fref0 clear;
|
||||||
|
filename &fref1 clear;
|
||||||
|
filename &fref2 clear;
|
||||||
|
libname &libref clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
data _null_;
|
||||||
|
infile &fref2;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend ms_creategroup;
|
||||||
@@ -87,9 +87,11 @@ data _null_;
|
|||||||
file &fref1 lrecl=1000;
|
file &fref1 lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put "Authorization: Bearer " _infile_;
|
if _n_=1 then do;
|
||||||
put "Content-Type: application/json";
|
put "Content-Type: application/json";
|
||||||
put "accept: application/json";
|
put "accept: application/json";
|
||||||
|
end;
|
||||||
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
|
|||||||
@@ -390,6 +390,11 @@ data _null_;
|
|||||||
put '%end; ';
|
put '%end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||||
|
put ' %if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then %do; ';
|
||||||
|
put ' /* functions in formats unsupported */ ';
|
||||||
|
put ' %put &sysmacroname: forcing missing back to NULL as feature not supported; ';
|
||||||
|
put ' %let missing=NULL; ';
|
||||||
|
put ' %end; ';
|
||||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||||
put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta ';
|
put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ data _null_;
|
|||||||
file &headref lrecl=1000;
|
file &headref lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put "Authorization: Bearer " _infile_;
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
proc http method='DELETE' headerin=&headref
|
proc http method='DELETE' headerin=&headref
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ data _null_;
|
|||||||
file &headref lrecl=1000;
|
file &headref lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put "Authorization: Bearer " _infile_;
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
proc http method='GET' out=&binaryfref headerin=&headref
|
proc http method='GET' out=&binaryfref headerin=&headref
|
||||||
|
|||||||
105
server/ms_getgroups.sas
Normal file
105
server/ms_getgroups.sas
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Fetches the list of groups from SASjs Server
|
||||||
|
@details Fetches the list of groups from SASjs Server and writes them to an
|
||||||
|
output dataset.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
%ms_getgroups(outds=userlist)
|
||||||
|
|
||||||
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
@param [out] outds= (work.ms_getgroups) This output dataset will contain the
|
||||||
|
list of groups. Format:
|
||||||
|
|NAME:$32.|DESCRIPTION:$64.|GROUPID:best.|
|
||||||
|
|---|---|---|
|
||||||
|
|`SomeGroup `|`A group `|`1`|
|
||||||
|
|`Another Group`|`this is a different group`|`2`|
|
||||||
|
|`admin`|`Administrators `|`3`|
|
||||||
|
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquelibref.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li ms_creategroup.sas
|
||||||
|
@li ms_getusers.test.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro ms_getgroups(
|
||||||
|
outds=work.ms_getgroups
|
||||||
|
,mdebug=0
|
||||||
|
);
|
||||||
|
|
||||||
|
%mp_abort(
|
||||||
|
iftrue=(&syscc ne 0)
|
||||||
|
,mac=ms_getusers.sas
|
||||||
|
,msg=%str(syscc=&syscc on macro entry)
|
||||||
|
)
|
||||||
|
|
||||||
|
%local fref0 fref1 libref optval rc msg;
|
||||||
|
%let fref0=%mf_getuniquefileref();
|
||||||
|
%let fref1=%mf_getuniquefileref();
|
||||||
|
%let libref=%mf_getuniquelibref();
|
||||||
|
|
||||||
|
/* avoid sending bom marker to API */
|
||||||
|
%let optval=%sysfunc(getoption(bomfile));
|
||||||
|
options nobomfile;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &fref0 lrecl=1000;
|
||||||
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
|
input;
|
||||||
|
if _n_=1 then put "accept: application/json";
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
data _null_;
|
||||||
|
infile &fref0;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
proc http method='GET' headerin=&fref0 out=&fref1
|
||||||
|
url="&_sasjs_apiserverurl/SASjsApi/group";
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
debug level=1;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(
|
||||||
|
iftrue=(&syscc ne 0)
|
||||||
|
,mac=ms_getgroups.sas
|
||||||
|
,msg=%str(Issue submitting GET query to SASjsApi/group)
|
||||||
|
)
|
||||||
|
|
||||||
|
libname &libref JSON fileref=&fref1;
|
||||||
|
|
||||||
|
data &outds;
|
||||||
|
length NAME $32 DESCRIPTION $64. GROUPID 8;
|
||||||
|
if _n_=1 then call missing(of _all_);
|
||||||
|
set &libref..root;
|
||||||
|
drop ordinal_root;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(
|
||||||
|
iftrue=(&syscc ne 0)
|
||||||
|
,mac=ms_getusers.sas
|
||||||
|
,msg=%str(Issue reading response JSON)
|
||||||
|
)
|
||||||
|
|
||||||
|
/* reset options */
|
||||||
|
options &optval;
|
||||||
|
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
filename &fref0 clear;
|
||||||
|
filename &fref1 clear;
|
||||||
|
libname &libref clear;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend ms_getgroups;
|
||||||
@@ -56,8 +56,8 @@ data _null_;
|
|||||||
file &fref0 lrecl=1000;
|
file &fref0 lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put "Authorization: Bearer " _infile_;
|
if _n_=1 then put "accept: application/json";
|
||||||
put "accept: application/json";
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ data _null_;
|
|||||||
file &authref lrecl=1000;
|
file &authref lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put 'Authorization: Bearer ' _infile_;
|
if _n_=1 then put "Content-Type: multipart/form-data; boundary=&boundary";
|
||||||
put "Content-Type: multipart/form-data; boundary=&boundary";
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
@@ -162,6 +162,7 @@ proc http method='POST' headerin=&authref in=&mainref out=&outref
|
|||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
|
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
|
||||||
|
or &mdebug=1
|
||||||
%then %do;
|
%then %do;
|
||||||
data _null_;infile &outref;input;putlog _infile_;run;
|
data _null_;infile &outref;input;putlog _infile_;run;
|
||||||
%end;
|
%end;
|
||||||
@@ -177,7 +178,7 @@ options &optval;
|
|||||||
%if &outlogds ne _null_ or &mdebug=1 %then %do;
|
%if &outlogds ne _null_ or &mdebug=1 %then %do;
|
||||||
%local dumplib;
|
%local dumplib;
|
||||||
%let dumplib=%mf_getuniquelibref();
|
%let dumplib=%mf_getuniquelibref();
|
||||||
libname &dumplib json (&outref);
|
libname &dumplib json fileref=&outref;
|
||||||
data &outlogds;
|
data &outlogds;
|
||||||
set &dumplib..log;
|
set &dumplib..log;
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
@@ -195,4 +196,4 @@ options &optval;
|
|||||||
filename &authref;
|
filename &authref;
|
||||||
filename &mainref;
|
filename &mainref;
|
||||||
%end;
|
%end;
|
||||||
%mend ms_runstp;
|
%mend ms_runstp;
|
||||||
|
|||||||
@@ -100,6 +100,11 @@
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%else %if &action=ARR or &action=OBJ %then %do;
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
|
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then %do;
|
||||||
|
/* functions in formats unsupported */
|
||||||
|
%put &sysmacroname: forcing missing back to NULL as feature not supported;
|
||||||
|
%let missing=NULL;
|
||||||
|
%end;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
,engine=DATASTEP,missing=&missing,showmeta=&showmeta
|
,engine=DATASTEP,missing=&missing,showmeta=&showmeta
|
||||||
)
|
)
|
||||||
|
|||||||
22
tests/crossplatform/mf_fmtdttm.test.sas
Normal file
22
tests/crossplatform/mf_fmtdttm.test.sas
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mf_fmtdttm macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_fmtdttm.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%global test1;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%let test1=%mf_fmtdttm();
|
||||||
|
%mp_assertscope(COMPARE,ignorelist=test1)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=("&test1"="DATETIME19.3" or "&test1"="E8601DT26.6"),
|
||||||
|
desc=Basic test,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
46
tests/crossplatform/mf_getvarcount.test.sas
Normal file
46
tests/crossplatform/mf_getvarcount.test.sas
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mf_getvarlist macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getvarcount.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
data work.all work.nums(keep=num1 num2) work.chars(keep=char1 char2);
|
||||||
|
length num1 num2 8 char1 char2 char3 $4;
|
||||||
|
call missing (of _all_);
|
||||||
|
output;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%put scope check:%mf_getvarcount(work.all);
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_getvarcount(work.all)=5),
|
||||||
|
desc=%str(Checking for mixed vars),
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_getvarcount(work.all,typefilter=C)=3),
|
||||||
|
desc=%str(Checking for char in mixed vars),
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_getvarcount(work.all,typefilter=N)=2),
|
||||||
|
desc=%str(Checking for num in mixed vars),
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_getvarcount(work.nums,typefilter=c)=0),
|
||||||
|
desc=%str(Checking for char in num vars),
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_getvarcount(work.chars,typefilter=N)=0),
|
||||||
|
desc=%str(Checking for num in char vars),
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
%mf_mkdir(&root/a/d)
|
%mf_mkdir(&root/a/d)
|
||||||
%mf_mkdir(&root/a/e)
|
%mf_mkdir(&root/a/e)
|
||||||
%mf_mkdir(&root/a/e/f)
|
%mf_mkdir(&root/a/e/f)
|
||||||
data "&root/a/e/f/ds1.sas7bdat";
|
libname test "&root/a/e/f";
|
||||||
|
data test.ds1;
|
||||||
x=1;
|
x=1;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,39 @@
|
|||||||
@li mp_filtercheck.sas
|
@li mp_filtercheck.sas
|
||||||
@li mp_assertdsobs.sas
|
@li mp_assertdsobs.sas
|
||||||
@li mp_assert.sas
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
/* set up test data */
|
||||||
|
data work.class ;
|
||||||
|
length name $8 sex $1 age height weight 8;
|
||||||
|
infile cards dsd;
|
||||||
|
input Name:$char. Sex :$char. Age Height Weight;
|
||||||
|
datalines4;
|
||||||
|
Alfred,M,14,69,112.5
|
||||||
|
Alice,F,13,56.5,84
|
||||||
|
Barbara,F,13,65.3,98
|
||||||
|
Carol,F,14,62.8,102.5
|
||||||
|
Henry,M,14,63.5,102.5
|
||||||
|
James,M,12,57.3,83
|
||||||
|
Jane,F,12,59.8,84.5
|
||||||
|
Janet,F,15,62.5,112.5
|
||||||
|
Jeffrey,M,13,62.5,84
|
||||||
|
John,M,12,59,99.5
|
||||||
|
Joyce,F,11,51.3,50.5
|
||||||
|
Judy,F,14,64.3,90
|
||||||
|
Louise,F,12,56.3,77
|
||||||
|
Mary,F,15,66.5,112
|
||||||
|
Philip,M,16,72,150
|
||||||
|
Robert,M,12,64.8,128
|
||||||
|
Ronald,M,15,67,133
|
||||||
|
Thomas,M,11,57.5,85
|
||||||
|
William,M,15,66.5,112
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
|
||||||
/* valid filter */
|
/* valid filter conditions */
|
||||||
data work.inds;
|
data work.inds;
|
||||||
infile datalines4 dsd;
|
infile datalines4 dsd;
|
||||||
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
||||||
@@ -21,14 +49,19 @@ AND,AND,1,SEX,<=,"'M'"
|
|||||||
AND,OR,2,Name,NOT IN,"('Jane','Alfred')"
|
AND,OR,2,Name,NOT IN,"('Jane','Alfred')"
|
||||||
AND,OR,2,Weight,>=,77.7
|
AND,OR,2,Weight,>=,77.7
|
||||||
AND,OR,2,Weight,NE,77.7
|
AND,OR,2,Weight,NE,77.7
|
||||||
|
AND,AND,1,age,=,.A
|
||||||
|
AND,AND,1,height,<,.B
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
%mp_filtercheck(work.inds,
|
%mp_filtercheck(work.inds,
|
||||||
targetds=sashelp.class,
|
targetds=work.class,
|
||||||
outds=work.badrecords,
|
outds=work.badrecords,
|
||||||
abort=NO
|
abort=NO
|
||||||
)
|
)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
%let syscc=0;
|
%let syscc=0;
|
||||||
%mp_assertdsobs(work.badrecords,
|
%mp_assertdsobs(work.badrecords,
|
||||||
desc=Valid filter query,
|
desc=Valid filter query,
|
||||||
@@ -49,7 +82,7 @@ AND,OR,2,Weight,>=,7
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,
|
%mp_filtercheck(work.inds,
|
||||||
targetds=sashelp.class,
|
targetds=work.class,
|
||||||
outds=work.badrecords,
|
outds=work.badrecords,
|
||||||
abort=NO
|
abort=NO
|
||||||
)
|
)
|
||||||
@@ -71,7 +104,7 @@ AND,OR,2,Name,NOT IN,"(''''Jane','Alfred')"
|
|||||||
run;
|
run;
|
||||||
|
|
||||||
%mp_filtercheck(work.inds,
|
%mp_filtercheck(work.inds,
|
||||||
targetds=sashelp.class,
|
targetds=work.class,
|
||||||
outds=work.badrecords,
|
outds=work.badrecords,
|
||||||
abort=NO
|
abort=NO
|
||||||
)
|
)
|
||||||
@@ -94,7 +127,7 @@ AND,OR,2,Weight,>=,7
|
|||||||
run;
|
run;
|
||||||
|
|
||||||
%mp_filtercheck(work.inds,
|
%mp_filtercheck(work.inds,
|
||||||
targetds=sashelp.class,
|
targetds=work.class,
|
||||||
outds=work.badrecords,
|
outds=work.badrecords,
|
||||||
abort=NO
|
abort=NO
|
||||||
)
|
)
|
||||||
@@ -115,7 +148,7 @@ AND,AND,1,age,=,;;%abort
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,
|
%mp_filtercheck(work.inds,
|
||||||
targetds=sashelp.class,
|
targetds=work.class,
|
||||||
outds=work.badrecords,
|
outds=work.badrecords,
|
||||||
abort=NO
|
abort=NO
|
||||||
)
|
)
|
||||||
@@ -137,7 +170,7 @@ AND,AND,1,age,=,0
|
|||||||
run;
|
run;
|
||||||
%let syscc=0;
|
%let syscc=0;
|
||||||
%mp_filtercheck(work.inds,
|
%mp_filtercheck(work.inds,
|
||||||
targetds=sashelp.class,
|
targetds=work.class,
|
||||||
outds=work.badrecords,
|
outds=work.badrecords,
|
||||||
abort=NO
|
abort=NO
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,6 +11,34 @@
|
|||||||
|
|
||||||
options source2;
|
options source2;
|
||||||
|
|
||||||
|
/* set up test data */
|
||||||
|
data work.class ;
|
||||||
|
length name $8 sex $1 age height weight 8;
|
||||||
|
infile cards dsd;
|
||||||
|
input Name:$char. Sex :$char. Age Height Weight;
|
||||||
|
datalines4;
|
||||||
|
Alfred,M,14,69,112.5
|
||||||
|
Alice,F,13,56.5,84
|
||||||
|
Barbara,F,13,65.3,98
|
||||||
|
Carol,F,14,62.8,102.5
|
||||||
|
Henry,M,14,63.5,102.5
|
||||||
|
James,M,12,57.3,83
|
||||||
|
Jane,F,12,59.8,84.5
|
||||||
|
Janet,F,15,62.5,112.5
|
||||||
|
Jeffrey,M,13,62.5,84
|
||||||
|
John,M,12,59,99.5
|
||||||
|
Joyce,F,11,51.3,50.5
|
||||||
|
Judy,F,14,64.3,90
|
||||||
|
Louise,F,12,56.3,77
|
||||||
|
Mary,F,15,66.5,112
|
||||||
|
Philip,M,16,72,150
|
||||||
|
Robert,M,12,64.8,128
|
||||||
|
Ronald,M,15,67,133
|
||||||
|
Thomas,M,11,57.5,85
|
||||||
|
William,M,15,66.5,112
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
|
||||||
/* valid filter */
|
/* valid filter */
|
||||||
data work.inds;
|
data work.inds;
|
||||||
infile datalines4 dsd;
|
infile datalines4 dsd;
|
||||||
@@ -23,10 +51,10 @@ AND,OR,2,Name,NOT IN,"('Jane','Janet')"
|
|||||||
AND,OR,2,Weight,>=,84.6
|
AND,OR,2,Weight,>=,84.6
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,targetds=sashelp.class)
|
%mp_filtercheck(work.inds,targetds=work.class)
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
data work.test;
|
data work.test;
|
||||||
set sashelp.class;
|
set work.class;
|
||||||
where %inc myfilter;;
|
where %inc myfilter;;
|
||||||
run;
|
run;
|
||||||
%mp_assertdsobs(work.test,
|
%mp_assertdsobs(work.test,
|
||||||
@@ -43,10 +71,10 @@ data work.inds;
|
|||||||
datalines4;
|
datalines4;
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,targetds=sashelp.class)
|
%mp_filtercheck(work.inds,targetds=work.class)
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
data work.test;
|
data work.test;
|
||||||
set sashelp.class;
|
set work.class;
|
||||||
where %inc myfilter;;
|
where %inc myfilter;;
|
||||||
run;
|
run;
|
||||||
%mp_assertdsobs(work.test,
|
%mp_assertdsobs(work.test,
|
||||||
@@ -64,10 +92,10 @@ datalines4;
|
|||||||
AND,OR,2,Name,IN,"('Jane','Janet')"
|
AND,OR,2,Name,IN,"('Jane','Janet')"
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,targetds=sashelp.class)
|
%mp_filtercheck(work.inds,targetds=work.class)
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
data work.test;
|
data work.test;
|
||||||
set sashelp.class;
|
set work.class;
|
||||||
where %inc myfilter;;
|
where %inc myfilter;;
|
||||||
run;
|
run;
|
||||||
%mp_assertdsobs(work.test,
|
%mp_assertdsobs(work.test,
|
||||||
@@ -86,10 +114,10 @@ OR,OR,2,Name,IN,"('Jane','Janet')"
|
|||||||
OR,OR,3,Name,IN,"('James')"
|
OR,OR,3,Name,IN,"('James')"
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,targetds=sashelp.class)
|
%mp_filtercheck(work.inds,targetds=work.class)
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
data work.test;
|
data work.test;
|
||||||
set sashelp.class;
|
set work.class;
|
||||||
where %inc myfilter;;
|
where %inc myfilter;;
|
||||||
run;
|
run;
|
||||||
%mp_assertdsobs(work.test,
|
%mp_assertdsobs(work.test,
|
||||||
@@ -108,10 +136,10 @@ AND,OR,2,Name,IN,"('Jane','Janet')"
|
|||||||
AND,OR,3,Name,IN,"('James')"
|
AND,OR,3,Name,IN,"('James')"
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtercheck(work.inds,targetds=sashelp.class)
|
%mp_filtercheck(work.inds,targetds=work.class)
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
data work.test;
|
data work.test;
|
||||||
set sashelp.class;
|
set work.class;
|
||||||
where %inc myfilter;;
|
where %inc myfilter;;
|
||||||
run;
|
run;
|
||||||
%mp_assertdsobs(work.test,
|
%mp_assertdsobs(work.test,
|
||||||
|
|||||||
@@ -10,6 +10,34 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
/* set up test data */
|
||||||
|
data work.class ;
|
||||||
|
length name $8 sex $1 age height weight 8;
|
||||||
|
infile cards dsd;
|
||||||
|
input Name:$char. Sex :$char. Age Height Weight;
|
||||||
|
datalines4;
|
||||||
|
Alfred,M,14,69,112.5
|
||||||
|
Alice,F,13,56.5,84
|
||||||
|
Barbara,F,13,65.3,98
|
||||||
|
Carol,F,14,62.8,102.5
|
||||||
|
Henry,M,14,63.5,102.5
|
||||||
|
James,M,12,57.3,83
|
||||||
|
Jane,F,12,59.8,84.5
|
||||||
|
Janet,F,15,62.5,112.5
|
||||||
|
Jeffrey,M,13,62.5,84
|
||||||
|
John,M,12,59,99.5
|
||||||
|
Joyce,F,11,51.3,50.5
|
||||||
|
Judy,F,14,64.3,90
|
||||||
|
Louise,F,12,56.3,77
|
||||||
|
Mary,F,15,66.5,112
|
||||||
|
Philip,M,16,72,150
|
||||||
|
Robert,M,12,64.8,128
|
||||||
|
Ronald,M,15,67,133
|
||||||
|
Thomas,M,11,57.5,85
|
||||||
|
William,M,15,66.5,112
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
|
||||||
libname permlib (work);
|
libname permlib (work);
|
||||||
|
|
||||||
%mp_coretable(LOCKTABLE,libds=permlib.locktable)
|
%mp_coretable(LOCKTABLE,libds=permlib.locktable)
|
||||||
@@ -31,7 +59,7 @@ AND,OR,2,Weight,NE,77.7
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mp_filterstore(libds=sashelp.class,
|
%mp_filterstore(libds=work.class,
|
||||||
queryds=work.inds,
|
queryds=work.inds,
|
||||||
filter_summary=permlib.filtsum,
|
filter_summary=permlib.filtsum,
|
||||||
filter_detail=permlib.filtdet,
|
filter_detail=permlib.filtdet,
|
||||||
@@ -60,7 +88,7 @@ select max(filter_rk) into: test1 from work.result;
|
|||||||
)
|
)
|
||||||
|
|
||||||
/* Test 2 - load same table again and ensure we get the same RK */
|
/* Test 2 - load same table again and ensure we get the same RK */
|
||||||
%mp_filterstore(libds=sashelp.class,
|
%mp_filterstore(libds=work.class,
|
||||||
queryds=work.inds,
|
queryds=work.inds,
|
||||||
filter_summary=permlib.filtsum,
|
filter_summary=permlib.filtsum,
|
||||||
filter_detail=permlib.filtdet,
|
filter_detail=permlib.filtdet,
|
||||||
|
|||||||
@@ -7,9 +7,36 @@
|
|||||||
@li mp_filtervalidate.sas
|
@li mp_filtervalidate.sas
|
||||||
@li mp_assertdsobs.sas
|
@li mp_assertdsobs.sas
|
||||||
@li mp_assert.sas
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
data work.class ;
|
||||||
|
length name $8 sex $1 age height weight 8;
|
||||||
|
infile cards dsd;
|
||||||
|
input Name:$char. Sex :$char. Age Height Weight;
|
||||||
|
datalines4;
|
||||||
|
Alfred,M,14,69,112.5
|
||||||
|
Alice,F,13,56.5,84
|
||||||
|
Barbara,F,13,65.3,98
|
||||||
|
Carol,F,14,62.8,102.5
|
||||||
|
Henry,M,14,63.5,102.5
|
||||||
|
James,M,12,57.3,83
|
||||||
|
Jane,F,12,59.8,84.5
|
||||||
|
Janet,F,15,62.5,112.5
|
||||||
|
Jeffrey,M,13,62.5,84
|
||||||
|
John,M,12,59,99.5
|
||||||
|
Joyce,F,11,51.3,50.5
|
||||||
|
Judy,F,14,64.3,90
|
||||||
|
Louise,F,12,56.3,77
|
||||||
|
Mary,F,15,66.5,112
|
||||||
|
Philip,M,16,72,150
|
||||||
|
Robert,M,12,64.8,128
|
||||||
|
Ronald,M,15,67,133
|
||||||
|
Thomas,M,11,57.5,85
|
||||||
|
William,M,15,66.5,112
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
|
||||||
/* valid filter */
|
/* valid filter */
|
||||||
data work.inds;
|
data work.inds;
|
||||||
@@ -21,10 +48,16 @@ AND,AND,1,AGE,>,5
|
|||||||
AND,AND,1,SEX,NE,"'M'"
|
AND,AND,1,SEX,NE,"'M'"
|
||||||
AND,OR,2,Name,NOT IN,"('Jane','Janet')"
|
AND,OR,2,Name,NOT IN,"('Jane','Janet')"
|
||||||
AND,OR,2,Weight,>=,84.6
|
AND,OR,2,Weight,>=,84.6
|
||||||
|
AND,AND,3,age,=,.a
|
||||||
|
AND,AND,4,weight,NE,._
|
||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
%mp_filtervalidate(myfilter,sashelp.class,outds=work.results,abort=NO)
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mp_filtervalidate(myfilter,work.class,outds=work.results,abort=NO)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
%mp_assertdsobs(work.results,
|
%mp_assertdsobs(work.results,
|
||||||
desc=Valid filter,
|
desc=Valid filter,
|
||||||
test=EMPTY,
|
test=EMPTY,
|
||||||
@@ -40,7 +73,7 @@ datalines4;
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
%mp_filtervalidate(myfilter,sashelp.class,outds=work.results,abort=NO)
|
%mp_filtervalidate(myfilter,work.class,outds=work.results,abort=NO)
|
||||||
%mp_assertdsobs(work.results,
|
%mp_assertdsobs(work.results,
|
||||||
desc=Empty filter,
|
desc=Empty filter,
|
||||||
test=EMPTY,
|
test=EMPTY,
|
||||||
@@ -59,7 +92,7 @@ AND,AND,1,SEX,NE,2
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
%mp_filtervalidate(myfilter,sashelp.class,outds=work.results,abort=NO)
|
%mp_filtervalidate(myfilter,work.class,outds=work.results,abort=NO)
|
||||||
%let syscc=0;
|
%let syscc=0;
|
||||||
%let test3=0;
|
%let test3=0;
|
||||||
data _null_;
|
data _null_;
|
||||||
@@ -84,7 +117,7 @@ AND,AND,1,age,NE,"'M'"
|
|||||||
;;;;
|
;;;;
|
||||||
run;
|
run;
|
||||||
%mp_filtergenerate(work.inds,outref=myfilter)
|
%mp_filtergenerate(work.inds,outref=myfilter)
|
||||||
%mp_filtervalidate(myfilter,sashelp.class,outds=work.results,abort=NO)
|
%mp_filtervalidate(myfilter,work.class,outds=work.results,abort=NO)
|
||||||
%let syscc=0;
|
%let syscc=0;
|
||||||
%let test4=0;
|
%let test4=0;
|
||||||
data _null_;
|
data _null_;
|
||||||
|
|||||||
@@ -6,24 +6,52 @@
|
|||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mp_getconstraints.sas
|
@li mp_getconstraints.sas
|
||||||
@li mp_assert.sas
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
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 unq unique(tx_from, dd_type),
|
|
||||||
constraint nnn not null(DD_SHORTDESC)
|
|
||||||
);
|
|
||||||
|
|
||||||
%mp_getconstraints(lib=work,ds=example,outds=work.constraints)
|
%macro conditional();
|
||||||
|
|
||||||
%mp_assert(
|
%if %sysfunc(exist(sashelp.vcncolu,view))=1 %then %do;
|
||||||
iftrue=(%mf_nobs(work.constraints)=6),
|
proc sql;
|
||||||
desc=Output table work.constraints created with correct number of records,
|
create table work.example(
|
||||||
outds=work.test_results
|
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 unq unique(tx_from, dd_type),
|
||||||
|
constraint nnn not null(DD_SHORTDESC)
|
||||||
|
);
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mp_getconstraints(lib=work,ds=example,outds=work.constraints)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_nobs(work.constraints)=6),
|
||||||
|
desc=Output table work.constraints created with correct number of records,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
proc sql;
|
||||||
|
create table work.example(
|
||||||
|
TX_FROM float format=datetime19.,
|
||||||
|
DD_TYPE char(16),
|
||||||
|
DD_SOURCE char(2048),
|
||||||
|
DD_SHORTDESC char(256)
|
||||||
|
);
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mp_getconstraints(lib=work,ds=example,outds=work.constraints)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_nobs(work.constraints)=0),
|
||||||
|
desc=Empty table created as constraints not supported,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
%mend conditional;
|
||||||
|
|
||||||
|
%conditional()
|
||||||
|
|||||||
@@ -10,10 +10,48 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
data work.class ;
|
||||||
|
attrib
|
||||||
|
Name length= $8
|
||||||
|
Sex length= $1
|
||||||
|
Age length= 8
|
||||||
|
Height length= 8
|
||||||
|
Weight length= 8
|
||||||
|
;
|
||||||
|
infile cards dsd;
|
||||||
|
input
|
||||||
|
Name :$char.
|
||||||
|
Sex :$char.
|
||||||
|
Age
|
||||||
|
Height
|
||||||
|
Weight
|
||||||
|
;
|
||||||
|
datalines4;
|
||||||
|
Alfred,M,14,69,112.5
|
||||||
|
Alice,F,13,56.5,84
|
||||||
|
Barbara,F,13,65.3,98
|
||||||
|
Carol,F,14,62.8,102.5
|
||||||
|
Henry,M,14,63.5,102.5
|
||||||
|
James,M,12,57.3,83
|
||||||
|
Jane,F,12,59.8,84.5
|
||||||
|
Janet,F,15,62.5,112.5
|
||||||
|
Jeffrey,M,13,62.5,84
|
||||||
|
John,M,12,59,99.5
|
||||||
|
Joyce,F,11,51.3,50.5
|
||||||
|
Judy,F,14,64.3,90
|
||||||
|
Louise,F,12,56.3,77
|
||||||
|
Mary,F,15,66.5,112
|
||||||
|
Philip,M,16,72,150
|
||||||
|
Robert,M,12,64.8,128
|
||||||
|
Ronald,M,15,67,133
|
||||||
|
Thomas,M,11,57.5,85
|
||||||
|
William,M,15,66.5,112
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
|
||||||
/* regular usage */
|
/* regular usage */
|
||||||
%mp_assertscope(SNAPSHOT)
|
%mp_assertscope(SNAPSHOT)
|
||||||
%mp_getmaxvarlengths(sashelp.class,outds=work.myds)
|
%mp_getmaxvarlengths(work.class,outds=work.myds)
|
||||||
%mp_assertscope(COMPARE,desc=checking scope leakage on mp_getmaxvarlengths)
|
%mp_assertscope(COMPARE,desc=checking scope leakage on mp_getmaxvarlengths)
|
||||||
%mp_assert(
|
%mp_assert(
|
||||||
iftrue=(&syscc=0),
|
iftrue=(&syscc=0),
|
||||||
|
|||||||
50
tests/serveronly/ms_creategroup.test.sas
Normal file
50
tests/serveronly/ms_creategroup.test.sas
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing ms_creategroup.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
@li ms_creategroup.sas
|
||||||
|
@li ms_getgroups.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%let group=%substr(%mf_getuniquename(),1,8);
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%ms_creategroup(&group, desc=The description,mdebug=&sasjs_mdebug,outds=test1)
|
||||||
|
%mp_assertscope(COMPARE
|
||||||
|
,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADPNUM MCLIB0_JADVLEN
|
||||||
|
)
|
||||||
|
|
||||||
|
%let id=0;
|
||||||
|
data _null_;
|
||||||
|
set work.test1;
|
||||||
|
call symputx('id',groupid);
|
||||||
|
run;
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&id>0),
|
||||||
|
desc=Checking that group was created with an ID,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
/* double check by querying the list of users */
|
||||||
|
%ms_getgroups(outds=work.test2)
|
||||||
|
%let checkid=0;
|
||||||
|
data _null_;
|
||||||
|
set work.test2;
|
||||||
|
where name="&group";
|
||||||
|
call symputx('checkid',groupid);
|
||||||
|
run;
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&checkid=&id),
|
||||||
|
desc=Checking that fetched group exists and has the same ID,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
23
tests/serveronly/ms_getgroups.test.sas
Normal file
23
tests/serveronly/ms_getgroups.test.sas
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing ms_getgroups.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li ms_getgroups.sas
|
||||||
|
@li mp_assertdsobs.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%ms_getgroups(outds=work.test1,mdebug=&sasjs_mdebug)
|
||||||
|
%mp_assertscope(COMPARE
|
||||||
|
,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADPNUM MCLIB0_JADVLEN
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.test1,test=ATLEAST 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user