mirror of
https://github.com/sasjs/core.git
synced 2025-12-13 23:44:35 +00:00
Compare commits
84 Commits
v2.29.2
...
sasjs-cli-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21200c11c1 | ||
|
|
825c97c49c | ||
|
|
f301899269 | ||
|
|
fc81f62d2f | ||
|
|
93aea5ed02 | ||
|
|
55d4c7238a | ||
|
|
cd75bf263a | ||
|
|
929a1a9974 | ||
|
|
7cafb4fb36 | ||
|
|
a8d222a0f8 | ||
|
|
ac0ddf38b0 | ||
|
|
ecd389c935 | ||
|
|
06a5ea06f8 | ||
|
|
955471ed3c | ||
|
|
c8d3b43b12 | ||
|
|
3e313b06a9 | ||
|
|
d7371a4505 | ||
|
|
32a6d15c2e | ||
|
|
b109e7cead | ||
| d291d3e287 | |||
|
|
5a2968e798 | ||
|
|
120ad9a7da | ||
|
|
67a81b2690 | ||
|
|
506cf1812f | ||
|
|
8cc0eb0dd7 | ||
|
|
4c1f69da3a | ||
|
|
f160ebe705 | ||
|
|
3f49925d01 | ||
|
|
53ed5dc916 | ||
|
|
808b24e31b | ||
|
|
c51c9c2ca9 | ||
|
|
4d6edf5566 | ||
|
|
41a24677f5 | ||
|
|
e7d8d8ffb3 | ||
|
|
60d23dd618 | ||
|
|
d2764c3cd1 | ||
|
|
f9f4355143 | ||
|
|
18bc6c889d | ||
|
|
42a16ef496 | ||
|
|
8178b801fb | ||
|
|
ce331a23c8 | ||
|
|
1cc9213467 | ||
|
|
aabbf4d0f9 | ||
|
|
2bea8be70d | ||
|
|
9b2368443e | ||
|
|
7915ba2c41 | ||
|
|
cc61e48868 | ||
|
|
62db83dcf6 | ||
|
|
7ea9e0f8e9 | ||
|
|
1c852515f5 | ||
|
|
b7e677bd8e | ||
|
|
f47f0d2cee | ||
|
|
3d0f426a98 | ||
|
|
2cb51f6164 | ||
|
|
b73bf998da | ||
|
|
c9ad38ee98 | ||
|
|
76b1b951c0 | ||
|
|
996054b17a | ||
|
|
7fca3d4e3f | ||
|
|
c4e599c861 | ||
|
|
0f6ff2cc1e | ||
|
|
7cac4c71fb | ||
|
|
1322bdab92 | ||
|
|
f201df606a | ||
|
|
a56fce86b1 | ||
|
|
41ccc5fdd9 | ||
|
|
b2877bd493 | ||
|
|
df8f8893e7 | ||
|
|
27fbdf193b | ||
|
|
6ae892989d | ||
|
|
39a7b332da | ||
|
|
c81794b542 | ||
|
|
e456da846a | ||
|
|
5c144be05b | ||
|
|
055669c133 | ||
|
|
4b67e13b24 | ||
|
|
f1ec3eda81 | ||
|
|
f2d5859675 | ||
|
|
ea057d4655 | ||
|
|
26c085b354 | ||
|
|
d13ac52739 | ||
|
|
bbbc28ad6d | ||
|
|
530cd6e95c | ||
|
|
c4e17e43e8 |
18
.git-hooks/commit-msg
Executable file
18
.git-hooks/commit-msg
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
RED="\033[1;31m"
|
||||||
|
GREEN="\033[1;32m"
|
||||||
|
|
||||||
|
# Get the commit message (the parameter we're given is just the path to the
|
||||||
|
# temporary file which holds the message).
|
||||||
|
commit_message=$(cat "$1")
|
||||||
|
|
||||||
|
if (echo "$commit_message" | grep -Eq "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z \-]+\))?!?: .+$") then
|
||||||
|
echo "${GREEN} ✔ Commit message meets Conventional Commit standards"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${RED}❌ Commit message does not meet the Conventional Commit standard!"
|
||||||
|
echo "An example of a valid message is:"
|
||||||
|
echo " feat(login): add the 'remember me' button"
|
||||||
|
echo "ℹ More details at: https://www.conventionalcommits.org/en/v1.0.0/#summary"
|
||||||
|
exit 1
|
||||||
2
.git-hooks/pre-commit
Executable file
2
.git-hooks/pre-commit
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
sasjs lint
|
||||||
30
.github/vpn/config.ovpn
vendored
Normal file
30
.github/vpn/config.ovpn
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
cipher AES-256-CBC
|
||||||
|
setenv FORWARD_COMPATIBLE 1
|
||||||
|
client
|
||||||
|
server-poll-timeout 4
|
||||||
|
nobind
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
remote vpn.analytium.co.uk 443 tcp
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
remote vpn.analytium.co.uk 1194 udp
|
||||||
|
dev tun
|
||||||
|
dev-type tun
|
||||||
|
ns-cert-type server
|
||||||
|
setenv opt tls-version-min 1.0 or-highest
|
||||||
|
reneg-sec 604800
|
||||||
|
sndbuf 0
|
||||||
|
rcvbuf 0
|
||||||
|
# NOTE: LZO commands are pushed by the Access Server at connect time.
|
||||||
|
# NOTE: The below line doesn't disable LZO.
|
||||||
|
comp-lzo no
|
||||||
|
verb 3
|
||||||
|
setenv PUSH_PEER_INFO
|
||||||
|
|
||||||
|
ca ca.crt
|
||||||
|
cert user.crt
|
||||||
|
key user.key
|
||||||
|
tls-auth tls.key 1
|
||||||
84
.github/workflows/run-tests.yml
vendored
Normal file
84
.github/workflows/run-tests.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||||
|
|
||||||
|
name: Node.js CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [12.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
|
- name: Write VPN Files
|
||||||
|
run: |
|
||||||
|
echo "$CA_CRT" > .github/vpn/ca.crt
|
||||||
|
echo "$USER_CRT" > .github/vpn/user.crt
|
||||||
|
echo "$USER_KEY" > .github/vpn/user.key
|
||||||
|
echo "$TLS_KEY" > .github/vpn/tls.key
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
CA_CRT: ${{ secrets.CA_CRT}}
|
||||||
|
USER_CRT: ${{ secrets.USER_CRT }}
|
||||||
|
USER_KEY: ${{ secrets.USER_KEY }}
|
||||||
|
TLS_KEY: ${{ secrets.TLS_KEY }}
|
||||||
|
|
||||||
|
- name: Install Open VPN
|
||||||
|
run: |
|
||||||
|
sudo apt install apt-transport-https
|
||||||
|
sudo wget https://swupdate.openvpn.net/repos/openvpn-repo-pkg-key.pub
|
||||||
|
sudo apt-key add openvpn-repo-pkg-key.pub
|
||||||
|
sudo wget -O /etc/apt/sources.list.d/openvpn3.list https://swupdate.openvpn.net/community/openvpn3/repos/openvpn3-bionic.list
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install openvpn3
|
||||||
|
|
||||||
|
- name: Start Open VPN 3
|
||||||
|
run: openvpn3 session-start --config .github/vpn/config.ovpn
|
||||||
|
|
||||||
|
- name: Install Doxygen
|
||||||
|
run: sudo apt-get install doxygen
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Check code style
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
- name: Add client
|
||||||
|
run: echo "CLIENT=${{secrets.CLIENT}}"> .env.viya
|
||||||
|
|
||||||
|
- name: Add secret
|
||||||
|
run: echo "SECRET=${{secrets.SECRET}}" >> .env.viya
|
||||||
|
|
||||||
|
- name: Add access token
|
||||||
|
run: echo "ACCESS_TOKEN=${{secrets.ACCESS_TOKEN}}" >> .env.viya
|
||||||
|
|
||||||
|
- name: Add refresh token
|
||||||
|
run: echo "REFRESH_TOKEN=${{secrets.REFRESH_TOKEN}}" >> .env.viya
|
||||||
|
|
||||||
|
- name: Build Project
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Run SASjs tests
|
||||||
|
run: npm run test
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
CLIENT: ${{secrets.CLIENT}}
|
||||||
|
SECRET: ${{secrets.SECRET}}
|
||||||
|
SAS_USERNAME: ${{secrets.SAS_USERNAME}}
|
||||||
|
SAS_PASSWORD: ${{secrets.SAS_PASSWORD}}
|
||||||
|
SERVER_URL: ${{secrets.SERVER_URL}}
|
||||||
|
SERVER_TYPE: ${{secrets.SERVER_TYPE}}
|
||||||
|
ACCESS_TOKEN: ${{secrets.ACCESS_TOKEN}}
|
||||||
|
REFRESH_TOKEN: ${{secrets.REFRESH_TOKEN}}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- init: npm i -g @sasjs/cli
|
- init: nvm install --latest-npm && npm i -g @sasjs/cli
|
||||||
|
|
||||||
image:
|
image:
|
||||||
file: .gitpod.dockerfile
|
file: .gitpod.dockerfile
|
||||||
|
|||||||
11
.npmignore
Normal file
11
.npmignore
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
all.sas
|
||||||
|
build.py
|
||||||
|
.gitpod*
|
||||||
|
tests/
|
||||||
|
sasjs/
|
||||||
|
.github/
|
||||||
|
.git-hooks/
|
||||||
|
.vscode/
|
||||||
|
main.dox
|
||||||
|
make_singlefile.sh
|
||||||
|
*.md
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
"noTrailingSpaces": true,
|
"noTrailingSpaces": true,
|
||||||
"noEncodedPasswords": true,
|
"noEncodedPasswords": true,
|
||||||
"hasDoxygenHeader": true,
|
"hasDoxygenHeader": true,
|
||||||
"hasMacroNameInMend": false,
|
"hasMacroNameInMend": true,
|
||||||
"hasMacroParentheses": true,
|
"hasMacroParentheses": true,
|
||||||
"noNestedMacros": false,
|
"noNestedMacros": false,
|
||||||
"noSpacesInFileNames": true,
|
"noSpacesInFileNames": true,
|
||||||
"maxLineLength": 135,
|
"maxLineLength": 230,
|
||||||
"lowerCaseFileNames": true,
|
"lowerCaseFileNames": true,
|
||||||
"noTabIndentation": true,
|
"noTabIndentation": true,
|
||||||
"indentationMultiple": 2
|
"indentationMultiple": 2
|
||||||
|
|||||||
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
As the changes are managed automatically in github, we don't generate an additional changelog. To view the fixes/features in each release, check out the releases page below:
|
||||||
|
|
||||||
|
[https://github.com/sasjs/core/releases](https://github.com/sasjs/core/releases)
|
||||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
https://sasapps.io/contact-us.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
||||||
30
README.md
30
README.md
@@ -1,4 +1,25 @@
|
|||||||
# Macro Core
|
# Macro Core
|
||||||
|
[![npm package][npm-image]][npm-url]
|
||||||
|
[![Github Workflow][githubworkflow-image]][githubworkflow-url]
|
||||||
|
[![Dependency Status][dependency-image]][dependency-url]
|
||||||
|
[]()
|
||||||
|

|
||||||
|
[](/LICENSE)
|
||||||
|

|
||||||
|
[](https://github.com/sasjs/core/issues?q=is%3Aissue+is%3Aclosed)
|
||||||
|
[](https://github.com/sasjs/core/issues)
|
||||||
|

|
||||||
|
[](https://gitpod.io/#https://github.com/sasjs/core)
|
||||||
|
|
||||||
|
|
||||||
|
[npm-image]:https://img.shields.io/npm/v/@sasjs/core.svg
|
||||||
|
[npm-url]:http://npmjs.org/package/@sasjs/core
|
||||||
|
[githubworkflow-image]:https://github.com/sasjs/core/actions/workflows/main.yml/badge.svg
|
||||||
|
[githubworkflow-url]:https://github.com/sasjs/core/blob/main/.github/workflows/main.yml
|
||||||
|
[dependency-image]:https://david-dm.org/sasjs/core.svg
|
||||||
|
[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/CONTRIBUTING.md) are welcomed.
|
||||||
|
|
||||||
@@ -149,3 +170,12 @@ When contributing to this library, it is therefore important to ensure that all
|
|||||||
# General Notes
|
# General Notes
|
||||||
|
|
||||||
- All macros should be compatible with SAS versions from support level B and above (so currently 9.2 and later). If an earlier version is not supported, then the macro should say as such in the header documentation, and exit gracefully (eg `%if %sysevalf(&sysver<9.3) %then %return`).
|
- All macros should be compatible with SAS versions from support level B and above (so currently 9.2 and later). If an earlier version is not supported, then the macro should say as such in the header documentation, and exit gracefully (eg `%if %sysevalf(&sysver<9.3) %then %return`).
|
||||||
|
|
||||||
|
## Star Gazing
|
||||||
|
|
||||||
|
If you find this library useful, please leave a [star](https://github.com/sasjs/core/stargazers) and help us grow our star graph!
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
SECURITY.md
Normal file
18
SECURITY.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
Security is an extremely high priority when it comes to the SASjs product suite. We take a number of steps across all repositories to minimise risk, such as:
|
||||||
|
|
||||||
|
* Regular dependabot updates
|
||||||
|
* Snyk reports
|
||||||
|
* Minimising dependencies, especially production dependencies (sasjs/core has NONE)
|
||||||
|
* Testing & Code review process
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
We support only the latest version
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
We welcome disclosures of all kinds in relation to all the SASjs libraries. You can submit them here: [https://sasapps.io/contact-us](https://sasapps.io/contact-us)
|
||||||
|
|
||||||
|
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief to be deprecated
|
@brief Abort, ungracefully
|
||||||
@details We will deprecate this macro in 2022
|
@details Will abort with a straightforward %abort if the condition is true.
|
||||||
|
|
||||||
As you can see, it's not a macro function.
|
<h4> Related Macros </h4>
|
||||||
|
@li mp_abort.sas
|
||||||
Use mp_abort.sas instead.
|
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@cond
|
@cond
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mf_abort(mac=mf_abort.sas, type=, msg=, iftrue=%str(1=1)
|
%macro mf_abort(mac=mf_abort.sas, type=deprecated, msg=, iftrue=%str(1=1)
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||||
@@ -21,116 +20,8 @@
|
|||||||
%if %length(&mac)>0 %then %put NOTE- called by &mac;
|
%if %length(&mac)>0 %then %put NOTE- called by &mac;
|
||||||
%put NOTE - &msg;
|
%put NOTE - &msg;
|
||||||
|
|
||||||
/* Stored Process Server web app context */
|
%abort;
|
||||||
%if %symexist(_metaperson) or "&SYSPROCESSNAME"="Compute Server" %then %do;
|
|
||||||
options obs=max replace nosyntaxcheck mprint;
|
|
||||||
/* extract log err / warn, if exist */
|
|
||||||
%local logloc logline;
|
|
||||||
%global logmsg; /* capture global messages */
|
|
||||||
%if %symexist(SYSPRINTTOLOG) %then %let logloc=&SYSPRINTTOLOG;
|
|
||||||
%else %let logloc=%qsysfunc(getoption(LOG));
|
|
||||||
proc printto log=log;run;
|
|
||||||
%if %length(&logloc)>0 %then %do;
|
|
||||||
%let logline=0;
|
|
||||||
data _null_;
|
|
||||||
infile &logloc lrecl=5000;
|
|
||||||
input; putlog _infile_;
|
|
||||||
i=1;
|
|
||||||
retain logonce 0;
|
|
||||||
if (
|
|
||||||
_infile_=:"%str(WARN)ING" or _infile_=:"%str(ERR)OR"
|
|
||||||
) and logonce=0
|
|
||||||
then do;
|
|
||||||
call symputx('logline',_n_);
|
|
||||||
logonce+1;
|
|
||||||
end;
|
|
||||||
run;
|
|
||||||
/* capture log including lines BEFORE the err */
|
|
||||||
%if &logline>0 %then %do;
|
|
||||||
data _null_;
|
|
||||||
infile &logloc lrecl=5000;
|
|
||||||
input;
|
|
||||||
i=1;
|
|
||||||
stoploop=0;
|
|
||||||
if _n_ ge &logline-5 and stoploop=0 then do until (i>12);
|
|
||||||
call symputx('logmsg',catx('\n',symget('logmsg'),_infile_));
|
|
||||||
input;
|
|
||||||
i+1;
|
|
||||||
stoploop=1;
|
|
||||||
end;
|
|
||||||
if stoploop=1 then stop;
|
|
||||||
run;
|
|
||||||
%end;
|
|
||||||
%end;
|
|
||||||
|
|
||||||
/* send response in SASjs JSON format */
|
%mend mf_abort;
|
||||||
data _null_;
|
|
||||||
file _webout mod lrecl=32000;
|
|
||||||
length msg $32767;
|
|
||||||
sasdatetime=datetime();
|
|
||||||
msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
|
|
||||||
/* escape the quotes */
|
|
||||||
msg=tranwrd(msg,'"','\"');
|
|
||||||
/* ditch the CRLFs as chrome complains */
|
|
||||||
msg=compress(msg,,'kw');
|
|
||||||
/* quote without quoting the quotes (which are escaped instead) */
|
|
||||||
msg=cats('"',msg,'"');
|
|
||||||
if symexist('_debug') then debug=symget('_debug');
|
|
||||||
if debug ge 131 then put '>>weboutBEGIN<<';
|
|
||||||
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
|
||||||
put ',"sasjsAbort" : [{';
|
|
||||||
put ' "MSG":' msg ;
|
|
||||||
put ' ,"MAC": "' "&mac" '"}]';
|
|
||||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
|
||||||
if symexist('_metauser') then do;
|
|
||||||
_METAUSER=quote(trim(symget('_METAUSER')));
|
|
||||||
put ",""_METAUSER"": " _METAUSER;
|
|
||||||
_METAPERSON=quote(trim(symget('_METAPERSON')));
|
|
||||||
put ',"_METAPERSON": ' _METAPERSON;
|
|
||||||
end;
|
|
||||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
|
||||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
|
||||||
put ",""SYSCC"" : ""&syscc"" ";
|
|
||||||
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
|
||||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
|
||||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
|
||||||
put "}" @;
|
|
||||||
%if &_debug ge 131 %then %do;
|
|
||||||
put '>>weboutEND<<';
|
|
||||||
%end;
|
|
||||||
run;
|
|
||||||
%let syscc=0;
|
|
||||||
%if %symexist(SYS_JES_JOB_URI) %then %do;
|
|
||||||
/* refer web service output to file service in one hit */
|
|
||||||
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
|
|
||||||
name="_webout.json";
|
|
||||||
%let rc=%sysfunc(fcopy(_web,_webout));
|
|
||||||
%end;
|
|
||||||
%else %do;
|
|
||||||
data _null_;
|
|
||||||
if symexist('sysprocessmode')
|
|
||||||
then if symget("sysprocessmode")="SAS Stored Process Server"
|
|
||||||
then rc=stpsrvset('program error', 0);
|
|
||||||
run;
|
|
||||||
%end;
|
|
||||||
/**
|
|
||||||
* endsas is reliable but kills some deployments.
|
|
||||||
* Abort variants are ungraceful (non zero return code)
|
|
||||||
* This approach lets SAS run silently until the end :-)
|
|
||||||
*/
|
|
||||||
%put _all_;
|
|
||||||
filename skip temp;
|
|
||||||
data _null_;
|
|
||||||
file skip;
|
|
||||||
put '%macro skip(); %macro skippy();';
|
|
||||||
run;
|
|
||||||
%inc skip;
|
|
||||||
%end;
|
|
||||||
%else %do;
|
|
||||||
%put _all_;
|
|
||||||
%abort cancel;
|
|
||||||
%end;
|
|
||||||
%mend;
|
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
@@ -23,4 +23,4 @@
|
|||||||
%if %sysfunc(exist(&libds)) ne 1 & %sysfunc(exist(&libds,VIEW)) ne 1 %then 0;
|
%if %sysfunc(exist(&libds)) ne 1 & %sysfunc(exist(&libds,VIEW)) ne 1 %then 0;
|
||||||
%else 1;
|
%else 1;
|
||||||
|
|
||||||
%mend;
|
%mend mf_existds;
|
||||||
|
|||||||
@@ -42,6 +42,6 @@
|
|||||||
-1
|
-1
|
||||||
%put &sysmacroname: &feature not found;
|
%put &sysmacroname: &feature not found;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_existfeature;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
@@ -24,4 +24,4 @@
|
|||||||
0
|
0
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mf_existfileref;
|
||||||
@@ -30,6 +30,6 @@
|
|||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mf_existvar;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
@@ -54,6 +54,6 @@
|
|||||||
0
|
0
|
||||||
%put Vars not found: &found;
|
%put Vars not found: &found;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_existvarlist;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
%sysfunc(attrc(&dsid,&attr))
|
%sysfunc(attrc(&dsid,&attr))
|
||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_getattrc;
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
%sysfunc(attrn(&dsid,&attr))
|
%sysfunc(attrn(&dsid,&attr))
|
||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_getattrn;
|
||||||
@@ -48,6 +48,6 @@
|
|||||||
|
|
||||||
&engine
|
&engine
|
||||||
|
|
||||||
%mend;
|
%mend mf_getengine;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
@@ -44,4 +44,4 @@
|
|||||||
%sysfunc(INPUTN(&bytes, best.),sizekmg.)
|
%sysfunc(INPUTN(&bytes, best.),sizekmg.)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend ;
|
%mend mf_getfilesize ;
|
||||||
@@ -29,4 +29,4 @@
|
|||||||
&valc
|
&valc
|
||||||
%end;
|
%end;
|
||||||
%else %put %str(ERR)OR: Unable to find key &key in ds &libds;
|
%else %put %str(ERR)OR: Unable to find key &key in ds &libds;
|
||||||
%mend;
|
%mend mf_getkeyvalue;
|
||||||
@@ -62,4 +62,4 @@
|
|||||||
%else %if &switch=VIYARESTAPI %then %do;
|
%else %if &switch=VIYARESTAPI %then %do;
|
||||||
%mf_trimstr(%sysfunc(getoption(servicesbaseurl)),/)
|
%mf_trimstr(%sysfunc(getoption(servicesbaseurl)),/)
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_getplatform;
|
||||||
@@ -50,4 +50,4 @@
|
|||||||
|
|
||||||
&buffer
|
&buffer
|
||||||
|
|
||||||
%mend;
|
%mend mf_getquotedstr;
|
||||||
@@ -38,6 +38,6 @@
|
|||||||
|
|
||||||
&schema
|
&schema
|
||||||
|
|
||||||
%mend;
|
%mend mf_getschema;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
|
|||||||
@@ -34,4 +34,4 @@
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%put unable to find available fileref in range &prefix.0-&maxtries;
|
%put unable to find available fileref in range &prefix.0-&maxtries;
|
||||||
%mend;
|
%mend mf_getuniquefileref;
|
||||||
@@ -37,4 +37,4 @@
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%put unable to find available libref in range &prefix.0-&maxtries;
|
%put unable to find available libref in range &prefix.0-&maxtries;
|
||||||
%mend;
|
%mend mf_getuniquelibref;
|
||||||
@@ -39,4 +39,4 @@
|
|||||||
|
|
||||||
%quote(&user)
|
%quote(&user)
|
||||||
|
|
||||||
%mend;
|
%mend mf_getuser;
|
||||||
|
|||||||
@@ -30,4 +30,4 @@
|
|||||||
%trim(&&&variable)
|
%trim(&&&variable)
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_getvalue;
|
||||||
@@ -29,4 +29,4 @@
|
|||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
&nvars
|
&nvars
|
||||||
%mend;
|
%mend mf_getvarcount;
|
||||||
@@ -49,4 +49,4 @@
|
|||||||
%let rc = %sysfunc(close(&dsid));
|
%let rc = %sysfunc(close(&dsid));
|
||||||
/* Return variable format */
|
/* Return variable format */
|
||||||
&vlen
|
&vlen
|
||||||
%mend;
|
%mend mf_getVarLen;
|
||||||
@@ -66,7 +66,8 @@
|
|||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put unable to open &libds (rc=&dsid);
|
%put &sysmacroname: Unable to open &libds (rc=&dsid);
|
||||||
|
%put &sysmacroname: SYSMSG= %sysfunc(sysmsg());
|
||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
&outvar
|
&outvar
|
||||||
|
|||||||
@@ -51,4 +51,4 @@ returns:
|
|||||||
/* Return variable number */
|
/* Return variable number */
|
||||||
&vnum.
|
&vnum.
|
||||||
|
|
||||||
%mend;
|
%mend mf_getVarNum;
|
||||||
@@ -40,4 +40,4 @@
|
|||||||
|
|
||||||
&engine
|
&engine
|
||||||
|
|
||||||
%mend;
|
%mend mf_getxengine;
|
||||||
|
|||||||
@@ -24,4 +24,4 @@
|
|||||||
|
|
||||||
%sysevalf(%superq(param)=,boolean)
|
%sysevalf(%superq(param)=,boolean)
|
||||||
|
|
||||||
%mend;
|
%mend mf_isblank;
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
|
|
||||||
&is_directory
|
&is_directory
|
||||||
|
|
||||||
%mend;
|
%mend mf_isdir;
|
||||||
@@ -26,4 +26,4 @@
|
|||||||
&root
|
&root
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mf_loc;
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ Usage:
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
/* exit quietly if directory did exist.*/
|
/* exit quietly if directory did exist.*/
|
||||||
%mend;
|
%mend mf_mkdir;
|
||||||
|
|||||||
@@ -16,4 +16,4 @@
|
|||||||
%if %symexist(&var) %then %do;
|
%if %symexist(&var) %then %do;
|
||||||
%superq(&var)
|
%superq(&var)
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mf_mval;
|
||||||
|
|||||||
@@ -23,4 +23,4 @@
|
|||||||
%macro mf_nobs(libds
|
%macro mf_nobs(libds
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%mf_getattrn(&libds,NLOBS)
|
%mf_getattrn(&libds,NLOBS)
|
||||||
%mend;
|
%mend mf_nobs;
|
||||||
@@ -47,4 +47,4 @@
|
|||||||
&basestr
|
&basestr
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mf_trimstr;
|
||||||
@@ -62,4 +62,4 @@
|
|||||||
%else %mf_abort(mac=mf_verifymacvars,type=&mabort,msg=&abortmsg);
|
%else %mf_abort(mac=mf_verifymacvars,type=&mabort,msg=&abortmsg);
|
||||||
%exit_success:
|
%exit_success:
|
||||||
|
|
||||||
%mend;
|
%mend mf_verifymacvars;
|
||||||
|
|||||||
@@ -50,5 +50,5 @@
|
|||||||
|
|
||||||
&outvar
|
&outvar
|
||||||
|
|
||||||
%mend;
|
%mend mf_wordsInStr1ButNotStr2;
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
|
|
||||||
/* send response in SASjs JSON format */
|
/* send response in SASjs JSON format */
|
||||||
data _null_;
|
data _null_;
|
||||||
file _webout mod lrecl=32000;
|
file _webout mod lrecl=32000 encoding='utf-8';
|
||||||
length msg $32767 debug $8;
|
length msg $32767 debug $8;
|
||||||
sasdatetime=datetime();
|
sasdatetime=datetime();
|
||||||
msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
|
msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
|
||||||
@@ -133,6 +133,8 @@
|
|||||||
put ",""SYSCC"" : ""&syscc"" ";
|
put ",""SYSCC"" : ""&syscc"" ";
|
||||||
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
||||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
|
sysvlong=quote(trim(symget('sysvlong')));
|
||||||
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||||
put "}" @;
|
put "}" @;
|
||||||
@@ -163,6 +165,7 @@
|
|||||||
sysuserid=symget('sysuserid');
|
sysuserid=symget('sysuserid');
|
||||||
iftrue=symget('iftrue');
|
iftrue=symget('iftrue');
|
||||||
put (_all_)(/=);
|
put (_all_)(/=);
|
||||||
|
call symputx('syscc',0);
|
||||||
abort cancel nolist;
|
abort cancel nolist;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
@@ -142,4 +142,4 @@
|
|||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds;
|
drop table &ds;
|
||||||
|
|
||||||
%mend;
|
%mend mp_assertcols;
|
||||||
@@ -144,4 +144,4 @@
|
|||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds;
|
drop table &ds;
|
||||||
|
|
||||||
%mend;
|
%mend mp_assertcolvals;
|
||||||
@@ -18,7 +18,11 @@
|
|||||||
@param [in] test= (HASOBS) The test to apply. Valid values are:
|
@param [in] test= (HASOBS) The test to apply. Valid values are:
|
||||||
@li HASOBS - Test is a PASS if the input dataset has any observations
|
@li HASOBS - Test is a PASS if the input dataset has any observations
|
||||||
@li EMPTY - Test is a PASS if input dataset is empty
|
@li EMPTY - Test is a PASS if input dataset is empty
|
||||||
@li EQUALS [integer] - Test passes if obs count matches the provided integer
|
@li EQUALS [integer] - Test passes if row count matches the provided integer
|
||||||
|
@LI ATLEAST [integer] - Test passes if row count is more than or equal to
|
||||||
|
the provided integer
|
||||||
|
@LI ATMOST [integer] - Test passes if row count is less than or equal to
|
||||||
|
the provided integer
|
||||||
@param [out] outds= (work.test_results) The output dataset to contain the
|
@param [out] outds= (work.test_results) The output dataset to contain the
|
||||||
results. If it does not exist, it will be created, with the following format:
|
results. If it does not exist, it will be created, with the following format:
|
||||||
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
||||||
@@ -27,6 +31,8 @@
|
|||||||
|
|
||||||
<h4> Related Macros </h4>
|
<h4> Related Macros </h4>
|
||||||
@li mp_assertcolvals.sas
|
@li mp_assertcolvals.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertcols.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -51,6 +57,22 @@
|
|||||||
)
|
)
|
||||||
%let test=EQUALS;
|
%let test=EQUALS;
|
||||||
%end;
|
%end;
|
||||||
|
%else %if %substr(&test.xxxxxxx,1,7)=ATLEAST %then %do;
|
||||||
|
%let val=%scan(&test,2,%str( ));
|
||||||
|
%mp_abort(iftrue= (%DATATYP(&val)=CHAR)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid test - &test, expected ATLEAST [integer])
|
||||||
|
)
|
||||||
|
%let test=ATLEAST;
|
||||||
|
%end;
|
||||||
|
%else %if %substr(&test.xxxxxxx,1,7)=ATMOST %then %do;
|
||||||
|
%let val=%scan(&test,2,%str( ));
|
||||||
|
%mp_abort(iftrue= (%DATATYP(&val)=CHAR)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid test - &test, expected ATMOST [integer])
|
||||||
|
)
|
||||||
|
%let test=ATMOST;
|
||||||
|
%end;
|
||||||
%else %if &test ne HASOBS and &test ne EMPTY %then %do;
|
%else %if &test ne HASOBS and &test ne EMPTY %then %do;
|
||||||
%mp_abort(
|
%mp_abort(
|
||||||
mac=&sysmacroname,
|
mac=&sysmacroname,
|
||||||
@@ -62,7 +84,8 @@
|
|||||||
length test_description $256 test_result $4 test_comments $256;
|
length test_description $256 test_result $4 test_comments $256;
|
||||||
test_description=symget('desc');
|
test_description=symget('desc');
|
||||||
test_result='FAIL';
|
test_result='FAIL';
|
||||||
test_comments="&sysmacroname: Dataset &inds has &nobs observations";
|
test_comments="&sysmacroname: Dataset &inds has &nobs observations.";
|
||||||
|
test_comments=test_comments!!" Test was "!!symget('test');
|
||||||
%if &test=HASOBS %then %do;
|
%if &test=HASOBS %then %do;
|
||||||
if &nobs>0 then test_result='PASS';
|
if &nobs>0 then test_result='PASS';
|
||||||
%end;
|
%end;
|
||||||
@@ -72,6 +95,12 @@
|
|||||||
%else %if &test=EQUALS %then %do;
|
%else %if &test=EQUALS %then %do;
|
||||||
if &nobs=&val then test_result='PASS';
|
if &nobs=&val then test_result='PASS';
|
||||||
%end;
|
%end;
|
||||||
|
%else %if &test=ATLEAST %then %do;
|
||||||
|
if &nobs ge &val then test_result='PASS';
|
||||||
|
%end;
|
||||||
|
%else %if &test=ATMOST %then %do;
|
||||||
|
if &nobs le &val then test_result='PASS';
|
||||||
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
||||||
%end;
|
%end;
|
||||||
@@ -86,4 +115,4 @@
|
|||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds;
|
drop table &ds;
|
||||||
|
|
||||||
%mend;
|
%mend mp_assertdsobs;
|
||||||
123
base/mp_base64copy.sas
Normal file
123
base/mp_base64copy.sas
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Convert a file to/from base64 format
|
||||||
|
@details Creates a new version of a file either encoded or decoded using
|
||||||
|
Base64. Inspired by this post by Michael Dixon:
|
||||||
|
https://support.selerity.com.au/hc/en-us/articles/223345708-Tip-SAS-and-Base64
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
filename tmp temp;
|
||||||
|
data _null_;
|
||||||
|
file tmp;
|
||||||
|
put 'base ik ally';
|
||||||
|
run;
|
||||||
|
%mp_base64copy(inref=tmp, outref=myref, action=ENCODE)
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile myref;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_base64copy(inref=myref, outref=mynewref, action=DECODE)
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile mynewref;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
@param [in] inref= Fileref of the input file (should exist)
|
||||||
|
@param [out] outref= Output fileref. If it does not exist, it is created.
|
||||||
|
@param [in] action= (ENCODE) The action to take. Valid values:
|
||||||
|
@li ENCODE - Convert the file to base64 format
|
||||||
|
@li DECODE - Decode the file from base64 format
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_base64copy(
|
||||||
|
inref=0,
|
||||||
|
outref=0,
|
||||||
|
action=ENCODE
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%let inref=%upcase(&inref);
|
||||||
|
%let outref=%upcase(&outref);
|
||||||
|
%let action=%upcase(&action);
|
||||||
|
%local infound outfound;
|
||||||
|
%let infound=0;
|
||||||
|
%let outfound=0;
|
||||||
|
data _null_;
|
||||||
|
set sashelp.vextfl(where=(fileref="&inref" or fileref="&outref"));
|
||||||
|
if fileref="&inref" then call symputx('infound',1,'l');
|
||||||
|
if fileref="&outref" then call symputx('outfound',1,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue= (&infound=0)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(INREF &inref NOT FOUND!)
|
||||||
|
)
|
||||||
|
%mp_abort(iftrue= (&outref=0)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(OUTREF NOT PROVIDED!)
|
||||||
|
)
|
||||||
|
%mp_abort(iftrue= (&action ne ENCODE and &action ne DECODE)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid action! Should be ENCODE OR DECODE)
|
||||||
|
)
|
||||||
|
|
||||||
|
%if &outfound=0 %then %do;
|
||||||
|
filename &outref temp lrecl=2097088;
|
||||||
|
%%end;
|
||||||
|
|
||||||
|
%if &action=ENCODE %then %do;
|
||||||
|
data _null_;
|
||||||
|
length b64 $ 76 line $ 57;
|
||||||
|
retain line "";
|
||||||
|
infile &inref recfm=F lrecl= 1 end=eof;
|
||||||
|
input @1 stream $char1.;
|
||||||
|
file &outref lrecl=76;
|
||||||
|
substr(line,(_N_-(CEIL(_N_/57)-1)*57),1) = byte(rank(stream));
|
||||||
|
if mod(_N_,57)=0 or EOF then do;
|
||||||
|
if eof then b64=put(trim(line),$base64X76.);
|
||||||
|
else b64=put(line, $base64X76.);
|
||||||
|
put b64;
|
||||||
|
line="";
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
%else %if &action=DECODE %then %do;
|
||||||
|
data _null_;
|
||||||
|
length filein 8 fileout 8;
|
||||||
|
filein = fopen("&inref",'I',4,'B');
|
||||||
|
fileout = fopen("&outref",'O',3,'B');
|
||||||
|
char= '20'x;
|
||||||
|
do while(fread(filein)=0);
|
||||||
|
raw="1234";
|
||||||
|
do i=1 to 4;
|
||||||
|
rc=fget(filein,char,1);
|
||||||
|
substr(raw,i,1)=char;
|
||||||
|
end;
|
||||||
|
val="123";
|
||||||
|
val=input(raw,$base64X4.);
|
||||||
|
do i=1 to 3;
|
||||||
|
length byte $1;
|
||||||
|
byte=byte(rank(substr(val,i,1)));
|
||||||
|
rc = fput(fileout, byte);
|
||||||
|
end;
|
||||||
|
rc =fwrite(fileout);
|
||||||
|
end;
|
||||||
|
rc = fclose(filein);
|
||||||
|
rc = fclose(fileout);
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend mp_base64copy;
|
||||||
@@ -53,4 +53,4 @@
|
|||||||
%if &outref=____out %then %do;
|
%if &outref=____out %then %do;
|
||||||
filename &outref clear;
|
filename &outref clear;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mp_binarycopy;
|
||||||
@@ -67,5 +67,5 @@
|
|||||||
else put inchar $char1.;
|
else put inchar $char1.;
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
%mend;
|
%mend mp_cleancsv;
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
@@ -64,4 +64,4 @@ data &outds;
|
|||||||
output;
|
output;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_createconstraints;
|
||||||
@@ -80,4 +80,4 @@ Usage:
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_createwebservice;
|
||||||
|
|||||||
@@ -141,4 +141,4 @@ data &outds
|
|||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_csv2ds;
|
||||||
@@ -49,4 +49,4 @@ data &outds;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_deleteconstraints;
|
||||||
@@ -167,4 +167,4 @@ run;
|
|||||||
by filepath file_or_folder filename ext ;
|
by filepath file_or_folder filename ext ;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mp_dirlist;
|
||||||
@@ -47,4 +47,4 @@
|
|||||||
%end;
|
%end;
|
||||||
as &outvar length=&varlen
|
as &outvar length=&varlen
|
||||||
from &libds;
|
from &libds;
|
||||||
%mend;
|
%mend mp_distinctfmtvalues;
|
||||||
@@ -251,4 +251,4 @@ quit;
|
|||||||
%put NOTE-;%put NOTE-;
|
%put NOTE-;%put NOTE-;
|
||||||
%put NOTE- %sysfunc(dequote(&cards_file.));
|
%put NOTE- %sysfunc(dequote(&cards_file.));
|
||||||
%put NOTE-;%put NOTE-;
|
%put NOTE-;%put NOTE-;
|
||||||
%mend;
|
%mend mp_ds2cards;
|
||||||
@@ -55,4 +55,4 @@ data _null_;
|
|||||||
run;
|
run;
|
||||||
|
|
||||||
|
|
||||||
%mend;
|
%mend mp_ds2csv;
|
||||||
@@ -99,4 +99,4 @@ filename &outref temp;
|
|||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_filtergenerate;
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ run;
|
|||||||
|
|
||||||
data &outds;
|
data &outds;
|
||||||
if &sqlrc or &syscc or &syserr then do;
|
if &sqlrc or &syscc or &syserr then do;
|
||||||
REASON_CD=coalescec(symget('SYSERRORTEXT'),symget('SYSWARNINGTEXT'));
|
REASON_CD='VALIDATION_ERROR: '!!
|
||||||
|
coalescec(symget('SYSERRORTEXT'),symget('SYSWARNINGTEXT'));
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
else stop;
|
else stop;
|
||||||
@@ -102,4 +103,4 @@ filename &fref1 clear;
|
|||||||
%let syscc=1008;
|
%let syscc=1008;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_filtervalidate;
|
||||||
|
|||||||
@@ -57,4 +57,4 @@ create table &outds as
|
|||||||
%end;
|
%end;
|
||||||
;
|
;
|
||||||
|
|
||||||
%mend;
|
%mend mp_getconstraints;
|
||||||
@@ -332,4 +332,4 @@ run;
|
|||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_getdbml;
|
||||||
@@ -115,7 +115,7 @@ create table _data_ as
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
%put &=constraints_used;
|
%put &=constraints_used;
|
||||||
%mend;
|
%mend addConst;
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
file &fref;
|
file &fref;
|
||||||
@@ -378,4 +378,4 @@ run;
|
|||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_getddl;
|
||||||
@@ -70,4 +70,4 @@ create table &outds (rename=(
|
|||||||
out=&outds(rename=(_name_=NAME COL1=MAXLEN));
|
out=&outds(rename=(_name_=NAME COL1=MAXLEN));
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_getmaxvarlengths;
|
||||||
@@ -301,4 +301,4 @@
|
|||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_guesspk;
|
||||||
@@ -72,4 +72,4 @@
|
|||||||
if &lastvar then output;
|
if &lastvar then output;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mp_hashdataset;
|
||||||
@@ -102,7 +102,8 @@
|
|||||||
%let fmtds=%scan(&syslast,2,.);
|
%let fmtds=%scan(&syslast,2,.);
|
||||||
/* prepare formats and varnames */
|
/* prepare formats and varnames */
|
||||||
data _null_;
|
data _null_;
|
||||||
set &fmtds end=last;
|
if _n_=1 then call symputx('nobs',nobs,'l');
|
||||||
|
set &fmtds end=last nobs=nobs;
|
||||||
name=upcase(name);
|
name=upcase(name);
|
||||||
/* fix formats */
|
/* fix formats */
|
||||||
if type=2 or type=6 then do;
|
if type=2 or type=6 then do;
|
||||||
@@ -128,7 +129,6 @@
|
|||||||
call symputx(cats('len',_n_),newlen,'l');
|
call symputx(cats('len',_n_),newlen,'l');
|
||||||
call symputx(cats('fmt',_n_),fmt,'l');
|
call symputx(cats('fmt',_n_),fmt,'l');
|
||||||
call symputx(cats('type',_n_),type,'l');
|
call symputx(cats('type',_n_),type,'l');
|
||||||
if last then call symputx('nobs',_n_,'l');
|
|
||||||
run;
|
run;
|
||||||
data &fmtds;
|
data &fmtds;
|
||||||
/* rename on entry */
|
/* rename on entry */
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
run;
|
run;
|
||||||
%let ds=&fmtds;
|
%let ds=&fmtds;
|
||||||
%end; /* &fmt=Y */
|
%end; /* &fmt=Y */
|
||||||
data _null_;file &jref mod ;
|
data _null_;file &jref mod encoding='utf-8';
|
||||||
put "["; call symputx('cols',0,'l');
|
put "["; call symputx('cols',0,'l');
|
||||||
proc sort
|
proc sort
|
||||||
data=sashelp.vcolumn(where=(libname='WORK' & memname="%upcase(&ds)"))
|
data=sashelp.vcolumn(where=(libname='WORK' & memname="%upcase(&ds)"))
|
||||||
|
|||||||
@@ -75,4 +75,4 @@ select distinct lowcase(memname)
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_lib2cards;
|
||||||
@@ -39,4 +39,4 @@
|
|||||||
,dttm=%sysfunc(datetime());
|
,dttm=%sysfunc(datetime());
|
||||||
quit;
|
quit;
|
||||||
|
|
||||||
%mend;
|
%mend mp_perflog;
|
||||||
@@ -85,4 +85,4 @@
|
|||||||
"with record &record and " _n_=;
|
"with record &record and " _n_=;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_prevobs;
|
||||||
@@ -87,4 +87,4 @@ insert into &outds select distinct * from &append_ds;
|
|||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_recursivejoin;
|
||||||
|
|||||||
@@ -30,4 +30,4 @@ data _null_;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_resetoption;
|
||||||
@@ -46,4 +46,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
%mend;
|
%mend mp_runddl;
|
||||||
@@ -117,4 +117,4 @@ proc sql
|
|||||||
|
|
||||||
%put process finished at %sysfunc(datetime(),datetime19.);
|
%put process finished at %sysfunc(datetime(),datetime19.);
|
||||||
|
|
||||||
%mend;
|
%mend mp_searchdata;
|
||||||
|
|||||||
@@ -49,4 +49,4 @@
|
|||||||
|
|
||||||
quit;
|
quit;
|
||||||
|
|
||||||
%mend;
|
%mend mp_setkeyvalue;
|
||||||
@@ -71,4 +71,4 @@
|
|||||||
proc append base=&libds data=&syslast nowarn;run;
|
proc append base=&libds data=&syslast nowarn;run;
|
||||||
|
|
||||||
options &etls_syntaxcheck;
|
options &etls_syntaxcheck;
|
||||||
%mend;
|
%mend mp_stprequests;
|
||||||
@@ -134,4 +134,4 @@ run;
|
|||||||
%mp_binarycopy(inloc="&inloc",outref=_webout)
|
%mp_binarycopy(inloc="&inloc",outref=_webout)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_streamfile;
|
||||||
|
|||||||
@@ -89,4 +89,4 @@ quit;
|
|||||||
libname &lib clear;
|
libname &lib clear;
|
||||||
|
|
||||||
|
|
||||||
%mend;
|
%mend mp_testjob;
|
||||||
@@ -22,8 +22,11 @@
|
|||||||
|mustbevalidname|can be anything, oops, %abort!!|
|
|mustbevalidname|can be anything, oops, %abort!!|
|
||||||
|
|
||||||
@param [in] debug= (log) Provide the _debug value
|
@param [in] debug= (log) Provide the _debug value
|
||||||
@param [in] viyaresult=(WEBOUT_JSON) The Viya result type to return. For
|
@param [in] mdebug= (0) Set to 1 to provide macro debugging
|
||||||
|
@param [in] viyaresult= (WEBOUT_JSON) The Viya result type to return. For
|
||||||
more info, see mv_getjobresult.sas
|
more info, see mv_getjobresult.sas
|
||||||
|
@param [in] viyacontext= (SAS Job Execution compute context) The Viya compute
|
||||||
|
context on which to run the service
|
||||||
@param [out] outlib= (0) Output libref to contain the final tables. Set to
|
@param [out] outlib= (0) Output libref to contain the final tables. Set to
|
||||||
0 if the service output is not in JSON format.
|
0 if the service output is not in JSON format.
|
||||||
@param [out] outref= (0) Output fileref to create, to contain the full _webout
|
@param [out] outref= (0) Output fileref to create, to contain the full _webout
|
||||||
@@ -47,17 +50,18 @@
|
|||||||
inputfiles=0,
|
inputfiles=0,
|
||||||
inputparams=0,
|
inputparams=0,
|
||||||
debug=log,
|
debug=log,
|
||||||
|
mdebug=0,
|
||||||
outlib=0,
|
outlib=0,
|
||||||
outref=0,
|
outref=0,
|
||||||
viyaresult=WEBOUT_JSON
|
viyaresult=WEBOUT_JSON,
|
||||||
|
viyacontext=SAS Job Execution compute context
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local mdebug;
|
%local dbg;
|
||||||
%if &debug ne 0 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
%let mdebug=1;
|
|
||||||
%put &sysmacroname entry vars:;
|
%put &sysmacroname entry vars:;
|
||||||
%put _local_;
|
%put _local_;
|
||||||
%end;
|
%end;
|
||||||
%else %let mdebug=0;
|
%else %let dbg=*;
|
||||||
|
|
||||||
/* sanitise inputparams */
|
/* sanitise inputparams */
|
||||||
%local pcnt;
|
%local pcnt;
|
||||||
@@ -212,6 +216,7 @@
|
|||||||
|
|
||||||
data &ds1;
|
data &ds1;
|
||||||
retain _program "&program";
|
retain _program "&program";
|
||||||
|
retain _contextname "&viyacontext";
|
||||||
set &ds1;
|
set &ds1;
|
||||||
putlog "&sysmacroname inputparams:";
|
putlog "&sysmacroname inputparams:";
|
||||||
putlog (_all_)(=);
|
putlog (_all_)(=);
|
||||||
|
|||||||
@@ -56,4 +56,4 @@ data &outds;
|
|||||||
duration_seconds=end_dttm-start_dttm;
|
duration_seconds=end_dttm-start_dttm;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_testwritespeedlibrary;
|
||||||
@@ -68,4 +68,4 @@ data &outds ;
|
|||||||
rc=filename('tmp');
|
rc=filename('tmp');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_tree;
|
||||||
@@ -63,4 +63,4 @@ data _null_;
|
|||||||
!!'filename &fname2 clear; filename &fname3 clear;');
|
!!'filename &fname2 clear; filename &fname3 clear;');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mp_unzip;
|
||||||
@@ -90,4 +90,4 @@ alter table &libds modify &var char(&len);
|
|||||||
|
|
||||||
%mp_createconstraints(inds=&dsconst,outds=&dsconst._addd,execute=YES)
|
%mp_createconstraints(inds=&dsconst,outds=&dsconst._addd,execute=YES)
|
||||||
|
|
||||||
%mend;
|
%mend mp_updatevarlength;
|
||||||
|
|||||||
@@ -76,4 +76,4 @@ ods package publish archive properties
|
|||||||
(archive_name="&outname..zip" archive_path="&outpath");
|
(archive_name="&outname..zip" archive_path="&outpath");
|
||||||
ods package close;
|
ods package close;
|
||||||
|
|
||||||
%mend;
|
%mend mp_zip;
|
||||||
2
build.py
2
build.py
@@ -23,7 +23,7 @@ for file in files:
|
|||||||
ml.write(" put '" + line.rstrip().replace("'","''") + " ';\n")
|
ml.write(" put '" + line.rstrip().replace("'","''") + " ';\n")
|
||||||
ml.write("run;\n\n")
|
ml.write("run;\n\n")
|
||||||
ml.write("%inc \"%sysfunc(pathname(work))/" + name + ".lua\";\n\n")
|
ml.write("%inc \"%sysfunc(pathname(work))/" + name + ".lua\";\n\n")
|
||||||
ml.write("%mend;\n")
|
ml.write("%mend " + name + ";\n")
|
||||||
|
|
||||||
ml.close()
|
ml.close()
|
||||||
|
|
||||||
|
|||||||
@@ -391,4 +391,4 @@ run;
|
|||||||
|
|
||||||
%inc "%sysfunc(pathname(work))/ml_json.lua";
|
%inc "%sysfunc(pathname(work))/ml_json.lua";
|
||||||
|
|
||||||
%mend;
|
%mend ml_json;
|
||||||
|
|||||||
7
main.dox
7
main.dox
@@ -42,6 +42,13 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*! \dir Tests
|
||||||
|
* \brief SASjs Tests
|
||||||
|
* \details These folders contain the macro tests. They are first compiled
|
||||||
|
and deployed (sasjs cbd) then executed (sasjs test).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/*! \dir viya
|
/*! \dir viya
|
||||||
* \brief Viya macros
|
* \brief Viya macros
|
||||||
* \details These macros have the following attributes:
|
* \details These macros have the following attributes:
|
||||||
|
|||||||
@@ -95,4 +95,4 @@ run;
|
|||||||
|
|
||||||
filename __us2grp clear;
|
filename __us2grp clear;
|
||||||
|
|
||||||
%mend;
|
%mend mm_adduser2group;
|
||||||
@@ -460,4 +460,4 @@ run;
|
|||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mm_assigndirectlib;
|
||||||
|
|||||||
@@ -75,4 +75,4 @@
|
|||||||
%else %do;
|
%else %do;
|
||||||
%put NOTE: Library &libref is already assigned;
|
%put NOTE: Library &libref is already assigned;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mm_assignlib;
|
||||||
|
|||||||
@@ -152,4 +152,4 @@ run;
|
|||||||
%else %put NOTE: Application (&name) successfully created in (&tree)!;
|
%else %put NOTE: Application (&name) successfully created in (&tree)!;
|
||||||
|
|
||||||
|
|
||||||
%mend;
|
%mend mm_createapplication;
|
||||||
@@ -80,4 +80,4 @@ data _null_;
|
|||||||
if last then call execute('call missing(of _all_);stop;run;');
|
if last then call execute('call missing(of _all_);stop;run;');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mend;
|
%mend mm_createdataset;
|
||||||
@@ -122,4 +122,4 @@ run;
|
|||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mm_createdocument;
|
||||||
@@ -157,4 +157,4 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%put &sysmacroname: execution finished for &path;
|
%put &sysmacroname: execution finished for &path;
|
||||||
%mend;
|
%mend mm_createfolder;
|
||||||
@@ -318,4 +318,4 @@ filename &frefout temp;
|
|||||||
filename &frefout clear;
|
filename &frefout clear;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mm_createlibrary;
|
||||||
|
|||||||
@@ -385,4 +385,4 @@ run;
|
|||||||
%put %str(WARN)ING: STPTYPE=*&stptype* not recognised!;
|
%put %str(WARN)ING: STPTYPE=*&stptype* not recognised!;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mm_createstp;
|
||||||
@@ -22,7 +22,7 @@ Usage:
|
|||||||
%webout(OBJ,example2) * Object format, easier to work with ;
|
%webout(OBJ,example2) * Object format, easier to work with ;
|
||||||
%webout(CLOSE)
|
%webout(CLOSE)
|
||||||
;;;;
|
;;;;
|
||||||
%mm_createwebservice(path=/Public/app/common,name=appInit)
|
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001)
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mm_createstp.sas
|
@li mm_createstp.sas
|
||||||
@@ -37,12 +37,15 @@ Usage:
|
|||||||
@param desc= The description of the service (optional)
|
@param desc= The description of the service (optional)
|
||||||
@param precode= Space separated list of filerefs, pointing to the code that
|
@param precode= Space separated list of filerefs, pointing to the code that
|
||||||
needs to be attached to the beginning of the service (optional)
|
needs to be attached to the beginning of the service (optional)
|
||||||
@param code= Space seperated fileref(s) of the actual code to be added
|
@param code=(ft15f001) Space seperated fileref(s) of the actual code to be
|
||||||
@param server= The server which will run the STP. Server name or uri is fine.
|
added
|
||||||
@param mDebug= set to 1 to show debug messages in the log
|
@param server=(SASApp) The server which will run the STP. Server name or uri
|
||||||
@param replace= select YES to replace any existing service in that location
|
is fine.
|
||||||
@param adapter= the macro uses the sasjs adapter by default. To use another
|
@param mDebug=(0) set to 1 to show debug messages in the log
|
||||||
adapter, add a (different) fileref here.
|
@param replace=(YES) select NO to avoid replacing an existing service in that
|
||||||
|
location
|
||||||
|
@param adapter=(sasjs) the macro uses the sasjs adapter by default. To use
|
||||||
|
another adapter, add a (different) fileref here.
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -52,11 +55,11 @@ Usage:
|
|||||||
%macro mm_createwebservice(path=
|
%macro mm_createwebservice(path=
|
||||||
,name=initService
|
,name=initService
|
||||||
,precode=
|
,precode=
|
||||||
,code=
|
,code=ft15f001
|
||||||
,desc=This stp was created automagically by the mm_createwebservice macro
|
,desc=This stp was created automagically by the mm_createwebservice macro
|
||||||
,mDebug=0
|
,mDebug=0
|
||||||
,server=SASApp
|
,server=SASApp
|
||||||
,replace=NO
|
,replace=YES
|
||||||
,adapter=sasjs
|
,adapter=sasjs
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
@@ -131,7 +134,8 @@ data _null_;
|
|||||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||||
put ' /* prepare formats and varnames */ ';
|
put ' /* prepare formats and varnames */ ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' set &fmtds end=last; ';
|
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
||||||
|
put ' set &fmtds end=last nobs=nobs; ';
|
||||||
put ' name=upcase(name); ';
|
put ' name=upcase(name); ';
|
||||||
put ' /* fix formats */ ';
|
put ' /* fix formats */ ';
|
||||||
put ' if type=2 or type=6 then do; ';
|
put ' if type=2 or type=6 then do; ';
|
||||||
@@ -157,7 +161,6 @@ data _null_;
|
|||||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' data &fmtds; ';
|
put ' data &fmtds; ';
|
||||||
put ' /* rename on entry */ ';
|
put ' /* rename on entry */ ';
|
||||||
@@ -176,7 +179,7 @@ data _null_;
|
|||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %let ds=&fmtds; ';
|
put ' %let ds=&fmtds; ';
|
||||||
put ' %end; /* &fmt=Y */ ';
|
put ' %end; /* &fmt=Y */ ';
|
||||||
put ' data _null_;file &jref mod ; ';
|
put ' data _null_;file &jref mod encoding=''utf-8''; ';
|
||||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||||
put ' proc sort ';
|
put ' proc sort ';
|
||||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
||||||
@@ -263,7 +266,12 @@ data _null_;
|
|||||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
put '%local i tempds; ';
|
put '%local i tempds jsonengine; ';
|
||||||
|
put ' ';
|
||||||
|
put '/* see https://github.com/sasjs/core/issues/41 */ ';
|
||||||
|
put '%if "%upcase(&SYSENCODING)" ne "UTF-8" %then %let jsonengine=PROCJSON; ';
|
||||||
|
put '%else %let jsonengine=DATASTEP; ';
|
||||||
|
put ' ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%if &action=FETCH %then %do; ';
|
put '%if &action=FETCH %then %do; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&_debug) ge 131 %then %do; ';
|
||||||
@@ -298,7 +306,7 @@ data _null_;
|
|||||||
put ' OPTIONS NOBOMFILE; ';
|
put ' OPTIONS NOBOMFILE; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' /** ';
|
put ' /** ';
|
||||||
put ' * check engine type to avoid the below err message: ';
|
put ' * check xengine type to avoid the below err message: ';
|
||||||
put ' * > Function is only valid for filerefs using the CACHE access method. ';
|
put ' * > Function is only valid for filerefs using the CACHE access method. ';
|
||||||
put ' */ ';
|
put ' */ ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
@@ -319,8 +327,8 @@ 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 ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||||
put ' ,engine=DATASTEP,dbg=%str(&_debug) ';
|
put ' ,engine=&jsonengine,dbg=%str(&_debug) ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
@@ -333,7 +341,7 @@ data _null_;
|
|||||||
put ' %local wtcnt;%let wtcnt=0; ';
|
put ' %local wtcnt;%let wtcnt=0; ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' set &tempds; ';
|
put ' set &tempds; ';
|
||||||
put ' if not (name =:"DATA"); ';
|
put ' if not (upcase(name) =:"DATA"); /* ignore temp datasets */ ';
|
||||||
put ' i+1; ';
|
put ' i+1; ';
|
||||||
put ' call symputx(''wt''!!left(i),name,''l''); ';
|
put ' call symputx(''wt''!!left(i),name,''l''); ';
|
||||||
put ' call symputx(''wtcnt'',i,''l''); ';
|
put ' call symputx(''wtcnt'',i,''l''); ';
|
||||||
@@ -353,8 +361,8 @@ data _null_;
|
|||||||
put ' put " ""&wt"" : {"; ';
|
put ' put " ""&wt"" : {"; ';
|
||||||
put ' put ''"nlobs":'' nlobs; ';
|
put ' put ''"nlobs":'' nlobs; ';
|
||||||
put ' put '',"nvars":'' nvars; ';
|
put ' put '',"nvars":'' nvars; ';
|
||||||
put ' %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP) ';
|
put ' %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine) ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine) ';
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -378,6 +386,8 @@ data _null_;
|
|||||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||||
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||||
|
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||||
|
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||||
put ' put "}" @; ';
|
put ' put "}" @; ';
|
||||||
@@ -387,7 +397,7 @@ data _null_;
|
|||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%mend; ';
|
put '%mend mm_webout; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro mf_getuser(type=META ';
|
put '%macro mf_getuser(type=META ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
@@ -405,7 +415,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put ' %quote(&user) ';
|
put ' %quote(&user) ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%mend; ';
|
put '%mend mf_getuser; ';
|
||||||
/* WEBOUT END */
|
/* WEBOUT END */
|
||||||
put '%macro webout(action,ds,dslabel=,fmt=);';
|
put '%macro webout(action,ds,dslabel=,fmt=);';
|
||||||
put ' %mm_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt)';
|
put ' %mm_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt)';
|
||||||
@@ -466,4 +476,4 @@ run;
|
|||||||
%put &url?_PROGRAM=&path/&name;
|
%put &url?_PROGRAM=&path/&name;
|
||||||
%put ;%put ;%put ;%put ;%put ;%put ;
|
%put ;%put ;%put ;%put ;%put ;%put ;
|
||||||
|
|
||||||
%mend;
|
%mend mm_createwebservice;
|
||||||
|
|||||||
@@ -68,4 +68,4 @@ run;
|
|||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mm_deletedocument;
|
||||||
|
|||||||
@@ -89,4 +89,4 @@ run;
|
|||||||
|
|
||||||
%put &sysmacroname: Library &name (&liburi) was successfully deleted;
|
%put &sysmacroname: Library &name (&liburi) was successfully deleted;
|
||||||
|
|
||||||
%mend;
|
%mend mm_deletelibrary;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user