mirror of
https://github.com/sasjs/core.git
synced 2026-01-08 01:50:05 +00:00
Merge pull request #99 from sasjs/issue98
feat: adding ms_webout macro for server responses on sasjs/server.
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
# http://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = false
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
|
|
||||||
0
CHANGELOG.md → .github/CHANGELOG.md
vendored
0
CHANGELOG.md → .github/CHANGELOG.md
vendored
0
SECURITY.md → .github/SECURITY.md
vendored
0
SECURITY.md → .github/SECURITY.md
vendored
55
README.md
55
README.md
@@ -1,7 +1,6 @@
|
|||||||
# Macro Core
|
# Macro Core
|
||||||
[![npm package][npm-image]][npm-url]
|
[![npm package][npm-image]][npm-url]
|
||||||
[![Github Workflow][githubworkflow-image]][githubworkflow-url]
|
[![Github Workflow][githubworkflow-image]][githubworkflow-url]
|
||||||
[![Dependency Status][dependency-image]][dependency-url]
|
|
||||||
[]()
|
[]()
|
||||||

|

|
||||||
[](/LICENSE)
|
[](/LICENSE)
|
||||||
@@ -16,11 +15,9 @@
|
|||||||
[npm-url]:http://npmjs.org/package/@sasjs/core
|
[npm-url]:http://npmjs.org/package/@sasjs/core
|
||||||
[githubworkflow-image]:https://github.com/sasjs/core/actions/workflows/main.yml/badge.svg
|
[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
|
[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
|
[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.
|
||||||
|
|
||||||
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:
|
||||||
@@ -32,49 +29,61 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
|||||||
|
|
||||||
Documentation: https://core.sasjs.io
|
Documentation: https://core.sasjs.io
|
||||||
|
|
||||||
# Components
|
## Components
|
||||||
|
|
||||||
**base** library (SAS9/Viya)
|
### **base** library (SAS9/Viya)
|
||||||
|
|
||||||
- OS independent
|
- OS independent
|
||||||
- Not metadata aware
|
- Not metadata aware
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mf_, _mp_
|
- Prefixes: _mf_, _mp_
|
||||||
|
|
||||||
**fcmp** library (SAS9/Viya)
|
#### **fcmp** library (SAS9/Viya)
|
||||||
- Function and macro names are identical, except for special cases
|
- Function and macro names are identical, except for special cases
|
||||||
- Prefixes: _mcf_
|
- Prefixes: _mcf_
|
||||||
|
|
||||||
The fcmp macros are used to generate fcmp functions, and can be used with or
|
The fcmp macros are used to generate fcmp functions, and can be used with or
|
||||||
without the `proc fcmp` wrapper.
|
without the `proc fcmp` wrapper.
|
||||||
|
|
||||||
**meta** library (SAS9 only)
|
### **meta** library (SAS9 only)
|
||||||
|
|
||||||
|
Macros used in SAS EBI, which connect to the metadata server.
|
||||||
|
|
||||||
- OS independent
|
- OS independent
|
||||||
- Metadata aware
|
- Metadata aware
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mm_
|
- Prefixes: _mm_
|
||||||
|
|
||||||
**viya** library (Viya only)
|
### **server** library (@sasjs/server only)
|
||||||
|
These macros are used for building applications using [@sasjs/server](https://server.sasjs.io) - an open source REST API for Desktop SAS.
|
||||||
|
|
||||||
|
- OS independent
|
||||||
|
- @sasjs/server aware
|
||||||
|
- No X command
|
||||||
|
- Prefixes: _ms_
|
||||||
|
|
||||||
|
### **viya** library (Viya only)
|
||||||
|
|
||||||
|
Macros used for interfacing with SAS Viya.
|
||||||
|
|
||||||
- OS independent
|
- OS independent
|
||||||
- No X command
|
- No X command
|
||||||
- Prefixes: _mv_
|
- Prefixes: _mv_, _mvf_
|
||||||
|
|
||||||
**metax** library (SAS9 only)
|
### **metax** library (SAS9 only)
|
||||||
|
|
||||||
- OS specific
|
- OS specific
|
||||||
- Metadata aware
|
- Metadata aware
|
||||||
- X command enabled
|
- X command enabled
|
||||||
- Prefixes: _mmw_,_mmu_,_mmx_
|
- Prefixes: _mmw_,_mmu_,_mmx_
|
||||||
|
|
||||||
**lua** library
|
### **lua** library
|
||||||
|
|
||||||
Wait - this is a macro library - what is LUA doing here? Well, it is a little known fact that you CAN run LUA within a SAS Macro. It has to be written to a text file with a `.lua` extension, from where you can `%include` it. So, without using the `proc lua` wrapper.
|
Wait - this is a macro library - what is LUA doing here? Well, it is a little known fact that you CAN run LUA within a SAS Macro. It has to be written to a text file with a `.lua` extension, from where you can `%include` it. So, without using the `proc lua` wrapper.
|
||||||
|
|
||||||
To contribute, simply write your freeform LUA in the LUA folder. Then run the `build.py`, which will convert your LUA into a data step with put statements, and create the macro wrapper with a `ml_` prefix. You can then use your module in any program by running:
|
To contribute, simply write your freeform LUA in the LUA folder. Then run the `build.py`, which will convert your LUA into a data step with put statements, and create the macro wrapper with a `ml_` prefix. You can then use your module in any program by running:
|
||||||
|
|
||||||
```
|
```sas
|
||||||
/* compile the lua module */
|
/* compile the lua module */
|
||||||
%ml_yourmodule()
|
%ml_yourmodule()
|
||||||
|
|
||||||
@@ -89,7 +98,7 @@ run;
|
|||||||
- X command enabled
|
- X command enabled
|
||||||
- Prefixes: _mmw_,_mmu_,_mmx_
|
- Prefixes: _mmw_,_mmu_,_mmx_
|
||||||
|
|
||||||
# Installation
|
## Installation
|
||||||
|
|
||||||
First, download the repo to a location your SAS system can access. Then update your sasautos path to include the components you wish to have available, eg:
|
First, download the repo to a location your SAS system can access. Then update your sasautos path to include the components you wish to have available, eg:
|
||||||
|
|
||||||
@@ -107,9 +116,9 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
|||||||
%inc mc;
|
%inc mc;
|
||||||
```
|
```
|
||||||
|
|
||||||
# Standards
|
## Standards
|
||||||
|
|
||||||
## File Properties
|
### File Properties
|
||||||
|
|
||||||
- filenames much match macro names
|
- filenames much match macro names
|
||||||
- filenames must be lowercase, without spaces
|
- filenames must be lowercase, without spaces
|
||||||
@@ -117,19 +126,20 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
|||||||
- one macro per file
|
- one macro per file
|
||||||
- prefixes:
|
- prefixes:
|
||||||
- _mf_ for macro functions (can be used in open code).
|
- _mf_ for macro functions (can be used in open code).
|
||||||
- _mp_ for macro procedures (which generate sas code)
|
- _ml_ for macros that are used to compile LUA modules
|
||||||
- _mm_ for metadata macros (interface with the metadata server).
|
- _mm_ for metadata macros (interface with the metadata server).
|
||||||
- _mmx_ for macros that use metadata and are XCMD enabled
|
- _mmx_ for macros that use metadata and are XCMD enabled
|
||||||
|
- _mp_ for macro procedures (which generate sas code)
|
||||||
|
- _ms_ for macro procedures that will only work with [@sasjs/server](https://github.com/sasjs/server)
|
||||||
|
- _mv_ for macro procedures that will only work in Viya
|
||||||
- _mx_ for macros that are XCMD enabled
|
- _mx_ for macros that are XCMD enabled
|
||||||
- _ml_ for macros that are used to compile LUA modules
|
|
||||||
- _mv_ for macros that will only work in Viya
|
|
||||||
- follow verb-noun convention
|
- follow verb-noun convention
|
||||||
- unix style line endings (lf)
|
- unix style line endings (lf)
|
||||||
- individual lines should be no more than 80 characters long
|
- individual lines should be no more than 80 characters long
|
||||||
- UTF-8
|
- UTF-8
|
||||||
|
|
||||||
|
|
||||||
## Header Properties
|
### Header Properties
|
||||||
|
|
||||||
The **Macro Core** documentation is created using [doxygen](http://www.doxygen.nl). A full list of attributes can be found [here](http://www.doxygen.nl/manual/commands.html) but the following are most relevant:
|
The **Macro Core** documentation is created using [doxygen](http://www.doxygen.nl). A full list of attributes can be found [here](http://www.doxygen.nl/manual/commands.html) but the following are most relevant:
|
||||||
|
|
||||||
@@ -143,7 +153,7 @@ The **Macro Core** documentation is created using [doxygen](http://www.doxygen.n
|
|||||||
|
|
||||||
All macros must be commented in the doxygen format, to enable the [online documentation](https://core.sasjs.io).
|
All macros must be commented in the doxygen format, to enable the [online documentation](https://core.sasjs.io).
|
||||||
|
|
||||||
### Dependencies
|
#### Dependencies
|
||||||
SAS code can contain one of two types of dependency - SAS Macros, and SAS Includes. When compiling projects using the [SASjs CLI](https://cli.sasjs.io) the doxygen header is scanned for ` @li` items under the following headers:
|
SAS code can contain one of two types of dependency - SAS Macros, and SAS Includes. When compiling projects using the [SASjs CLI](https://cli.sasjs.io) the doxygen header is scanned for ` @li` items under the following headers:
|
||||||
|
|
||||||
```sas
|
```sas
|
||||||
@@ -161,7 +171,7 @@ The CLI can then extract all the dependencies and insert as precode (SAS Macros)
|
|||||||
When contributing to this library, it is therefore important to ensure that all dependencies are listed in the header in this format.
|
When contributing to this library, it is therefore important to ensure that all dependencies are listed in the header in this format.
|
||||||
|
|
||||||
|
|
||||||
## Coding Standards
|
### Coding Standards
|
||||||
|
|
||||||
- Indentation = 2 spaces. No tabs!
|
- Indentation = 2 spaces. No tabs!
|
||||||
- no trailing white space
|
- no trailing white space
|
||||||
@@ -174,7 +184,7 @@ When contributing to this library, it is therefore important to ensure that all
|
|||||||
- Avoid naming collisions! All macro variables should be local scope. Use system generated work tables where possible - eg `data ; set sashelp.class; run; data &output; set &syslast; run;`
|
- Avoid naming collisions! All macro variables should be local scope. Use system generated work tables where possible - eg `data ; set sashelp.class; run; data &output; set &syslast; run;`
|
||||||
- The use of `quit;` for `proc sql` is optional unless you are looking to benefit from the timing statistics.
|
- The use of `quit;` for `proc sql` is optional unless you are looking to benefit from the timing statistics.
|
||||||
|
|
||||||
# General Notes
|
## General Notes
|
||||||
|
|
||||||
- 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`).
|
||||||
|
|
||||||
@@ -186,7 +196,6 @@ If you find this library useful, please leave a [star](https://github.com/sasjs/
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 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-)
|
||||||
|
|||||||
2
build.py
2
build.py
@@ -84,7 +84,7 @@ options noquotelenmax;
|
|||||||
"""
|
"""
|
||||||
f = open('all.sas', "w") # r / r+ / rb / rb+ / w / wb
|
f = open('all.sas', "w") # r / r+ / rb / rb+ / w / wb
|
||||||
f.write(header)
|
f.write(header)
|
||||||
folders=['base','meta','metax','viya','lua','fcmp']
|
folders=['base','meta','metax','server','viya','lua','fcmp']
|
||||||
for folder in folders:
|
for folder in folders:
|
||||||
filenames = [fn for fn in Path('./' + folder).iterdir() if fn.match("*.sas")]
|
filenames = [fn for fn in Path('./' + folder).iterdir() if fn.match("*.sas")]
|
||||||
filenames.sort()
|
filenames.sort()
|
||||||
|
|||||||
15
main.dox
15
main.dox
@@ -55,7 +55,18 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \dir Tests
|
/*! \dir server
|
||||||
|
* \brief Macros used with [sasjs/server](https://server.sasjs.io)
|
||||||
|
* \details These macros have the following attributes:
|
||||||
|
|
||||||
|
* OS independent
|
||||||
|
* sasjs/server aware
|
||||||
|
* No X command
|
||||||
|
* Prefixes: _ms_
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \dir tests
|
||||||
* \brief SASjs Tests
|
* \brief SASjs Tests
|
||||||
* \details These folders contain the macro tests. They are first compiled
|
* \details These folders contain the macro tests. They are first compiled
|
||||||
and deployed (sasjs cbd) then executed (sasjs test).
|
and deployed (sasjs cbd) then executed (sasjs test).
|
||||||
@@ -72,7 +83,7 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \dir lua
|
/*! \dir lua
|
||||||
* \brief Lua macros
|
* \brief Lua macros
|
||||||
* \details These macros have the following attributes:
|
* \details These macros have the following attributes:
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Concatenate all macros into a single file
|
|
||||||
|
|
||||||
OUTFILE='./macrocore.sas'
|
|
||||||
|
|
||||||
cat > $OUTFILE <<'EOL'
|
|
||||||
/**
|
|
||||||
@file
|
|
||||||
@brief Auto-generated file
|
|
||||||
@details
|
|
||||||
This file contains all the macros in a single file - which means it can be
|
|
||||||
'included' in SAS with just 2 lines of code:
|
|
||||||
|
|
||||||
filename mc url
|
|
||||||
"https://raw.githubusercontent.com/sasjs/core/main/macrocore.sas";
|
|
||||||
%inc mc;
|
|
||||||
|
|
||||||
The `build.sh` file in the https://github.com/sasjs/core repo
|
|
||||||
is used to create this file.
|
|
||||||
|
|
||||||
@author Allan Bowe
|
|
||||||
**/
|
|
||||||
EOL
|
|
||||||
|
|
||||||
cat base/* >> $OUTFILE
|
|
||||||
cat meta/* >> $OUTFILE
|
|
||||||
cat metax/* >> $OUTFILE
|
|
||||||
cat viya/* >> $OUTFILE
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
"fcmp",
|
"fcmp",
|
||||||
"meta",
|
"meta",
|
||||||
"metax",
|
"metax",
|
||||||
|
"server",
|
||||||
"viya",
|
"viya",
|
||||||
"lua",
|
"lua",
|
||||||
"tests/crossplatform"
|
"tests/crossplatform"
|
||||||
@@ -55,6 +56,18 @@
|
|||||||
"deployServicePack": true
|
"deployServicePack": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "server",
|
||||||
|
"serverUrl": "https://sas.analytium.co.uk:5001",
|
||||||
|
"serverType": "SASJS",
|
||||||
|
"appLoc": "/Shared Data/temp/macrocore",
|
||||||
|
"macroFolders": [
|
||||||
|
"tests/serveronly"
|
||||||
|
],
|
||||||
|
"deployConfig": {
|
||||||
|
"deployServicePack": true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "docsonly",
|
"name": "docsonly",
|
||||||
"serverType": "SAS9",
|
"serverType": "SAS9",
|
||||||
|
|||||||
170
server/ms_webout.sas
Normal file
170
server/ms_webout.sas
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Send data to/from @sasjs/server
|
||||||
|
@details This macro should be added to the start of each web service,
|
||||||
|
**immediately** followed by a call to:
|
||||||
|
|
||||||
|
%ms_webout(FETCH)
|
||||||
|
|
||||||
|
This will read all the input data and create same-named SAS datasets in the
|
||||||
|
WORK library. You can then insert your code, and send data back using the
|
||||||
|
following syntax:
|
||||||
|
|
||||||
|
data some datasets; * make some data ;
|
||||||
|
retain some columns;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%ms_webout(OPEN)
|
||||||
|
%ms_webout(ARR,some) * Array format, fast, suitable for large tables ;
|
||||||
|
%ms_webout(OBJ,datasets) * Object format, easier to work with ;
|
||||||
|
%ms_webout(CLOSE)
|
||||||
|
|
||||||
|
|
||||||
|
@param action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
||||||
|
@param ds The dataset to send back to the frontend
|
||||||
|
@param dslabel= value to use instead of the real name for sending to JSON
|
||||||
|
@param fmt=(Y) Set to N to send back unformatted values
|
||||||
|
@param fref=(_webout) The fileref to which to write the JSON
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_jsonout.sas
|
||||||
|
@li mf_getuser.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mv_webout.sas
|
||||||
|
@li mm_webout.sas
|
||||||
|
|
||||||
|
@version 9.3
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y);
|
||||||
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
|
sasjs_tables;
|
||||||
|
|
||||||
|
%local i tempds;
|
||||||
|
%let action=%upcase(&action);
|
||||||
|
|
||||||
|
%if &action=FETCH %then %do;
|
||||||
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
|
options mprint notes mprintnest;
|
||||||
|
%end;
|
||||||
|
%let _webin_file_count=%eval(&_webin_file_count+0);
|
||||||
|
/* now read in the data */
|
||||||
|
%do i=1 %to &_webin_file_count;
|
||||||
|
%if &_webin_file_count=1 %then %do;
|
||||||
|
%let _webin_fileref1=&_webin_fileref;
|
||||||
|
%let _webin_name1=&_webin_name;
|
||||||
|
%end;
|
||||||
|
data _null_;
|
||||||
|
infile &&_webin_fileref&i termstr=crlf;
|
||||||
|
input;
|
||||||
|
call symputx('input_statement',_infile_);
|
||||||
|
putlog "&&_webin_name&i input statement: " _infile_;
|
||||||
|
stop;
|
||||||
|
data &&_webin_name&i;
|
||||||
|
infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding='utf-8';
|
||||||
|
input &input_statement;
|
||||||
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
|
if _n_<20 then putlog _infile_;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
%let sasjs_tables=&sasjs_tables &&_webin_name&i;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%else %if &action=OPEN %then %do;
|
||||||
|
/* fix encoding */
|
||||||
|
OPTIONS NOBOMFILE;
|
||||||
|
|
||||||
|
/* setup json */
|
||||||
|
data _null_;file &fref encoding='utf-8';
|
||||||
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
|
put '>>weboutBEGIN<<';
|
||||||
|
%end;
|
||||||
|
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||||
|
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
||||||
|
run;
|
||||||
|
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
|
,engine=&jsonengine,dbg=%str(&_debug)
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
%else %if &action=CLOSE %then %do;
|
||||||
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
|
/* if debug mode, send back first 10 records of each work table also */
|
||||||
|
options obs=10;
|
||||||
|
data;run;%let tempds=%scan(&syslast,2,.);
|
||||||
|
ods output Members=&tempds;
|
||||||
|
proc datasets library=WORK memtype=data;
|
||||||
|
%local wtcnt;%let wtcnt=0;
|
||||||
|
data _null_;
|
||||||
|
set &tempds;
|
||||||
|
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||||
|
i+1;
|
||||||
|
call symputx('wt'!!left(i),name,'l');
|
||||||
|
call symputx('wtcnt',i,'l');
|
||||||
|
data _null_; file &fref mod encoding='utf-8';
|
||||||
|
put ",""WORK"":{";
|
||||||
|
%do i=1 %to &wtcnt;
|
||||||
|
%let wt=&&wt&i;
|
||||||
|
proc contents noprint data=&wt
|
||||||
|
out=_data_ (keep=name type length format:);
|
||||||
|
run;%let tempds=%scan(&syslast,2,.);
|
||||||
|
data _null_; file &fref mod encoding='utf-8';
|
||||||
|
dsid=open("WORK.&wt",'is');
|
||||||
|
nlobs=attrn(dsid,'NLOBS');
|
||||||
|
nvars=attrn(dsid,'NVARS');
|
||||||
|
rc=close(dsid);
|
||||||
|
if &i>1 then put ','@;
|
||||||
|
put " ""&wt"" : {";
|
||||||
|
put '"nlobs":' nlobs;
|
||||||
|
put ',"nvars":' nvars;
|
||||||
|
%mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine)
|
||||||
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine)
|
||||||
|
data _null_; file &fref mod encoding='utf-8';
|
||||||
|
put "}";
|
||||||
|
%end;
|
||||||
|
data _null_; file &fref mod encoding='utf-8';
|
||||||
|
put "}";
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
/* close off json */
|
||||||
|
data _null_;file &fref mod encoding='utf-8';
|
||||||
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||||
|
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||||
|
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
||||||
|
put ",""_DEBUG"" : ""&_debug"" ";
|
||||||
|
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||||
|
put ",""SYSCC"" : ""&syscc"" ";
|
||||||
|
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
||||||
|
SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG')));
|
||||||
|
put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG;
|
||||||
|
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||||
|
put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
|
||||||
|
put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
|
||||||
|
put ",""SYSPROCESSNAME"" : ""&SYSPROCESSNAME"" ";
|
||||||
|
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||||
|
put ",""SYSSCPL"" : ""&sysscpl"" ";
|
||||||
|
put ",""SYSSITE"" : ""&syssite"" ";
|
||||||
|
put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" ";
|
||||||
|
sysvlong=quote(trim(symget('sysvlong')));
|
||||||
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
|
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||||
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||||
|
autoexec=quote(trim(getoption('autoexec')));
|
||||||
|
put ',"AUTOEXEC" : ' autoexec;
|
||||||
|
memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)";
|
||||||
|
put ',"MEMSIZE" : ' memsize;
|
||||||
|
put "}" @;
|
||||||
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
|
put '>>weboutEND<<';
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend ms_webout;
|
||||||
35
tests/serveronly/ms_webout.test.sas
Normal file
35
tests/serveronly/ms_webout.test.sas
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing ms_webout macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li ms_webout.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
%let fref=%mf_getuniquefileref();
|
||||||
|
%global _metaperson;
|
||||||
|
data some datasets;
|
||||||
|
x=1;
|
||||||
|
run;
|
||||||
|
%ms_webout(OPEN,fref=&fref)
|
||||||
|
%ms_webout(ARR,some,fref=&fref)
|
||||||
|
%ms_webout(OBJ,datasets,fref=&fref)
|
||||||
|
%ms_webout(CLOSE,fref=&fref)
|
||||||
|
|
||||||
|
libname test JSON (&fref);
|
||||||
|
data root;
|
||||||
|
set test.root;
|
||||||
|
call symputx('checkval',sysvlong);
|
||||||
|
run;
|
||||||
|
data alldata;
|
||||||
|
set test.alldata;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%str(&checkval)=%str(&sysvlong)),
|
||||||
|
desc=Check if the sysvlong value was created
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user