1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-12 23:14:35 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Allan Bowe
4df8f3b4c2 feat: mv_getjobcode macro, introducing LUA macros 2021-01-03 22:16:11 +00:00
Allan Bowe
11aa484996 chore: documentation 2020-12-30 17:06:04 +00:00
Allan Bowe
b9fd79bd5e fix: debugging in mm_assignlib 2020-12-25 16:58:30 +00:00
Allan Bowe
1beb30d0ff fix: updating <h4> Dependencies </h4> in header to be <h4> SAS Macros </h4> in line with the updated SASjs compilation process (which distinguishes between SAS Macro and SAS Program dependencies)
BREAKING CHANGE - this doesn't break anything in the framework but I know of at least one old project that uses the <h4> Dependencies </h4> tag to perform backend compilation, so am bumping the version to be safe (looking at you, Chris
2020-12-25 10:36:19 +00:00
Allan Bowe
e334ea9b85 chore: all.sas update 2020-12-25 10:22:44 +00:00
Allan Bowe
c090c8d53b feat: simple macro to test the write speed for a library (very very basic) 2020-12-25 10:18:02 +00:00
Allan Bowe
659339bd98 fix: more comments in mp_prevobs 2020-12-25 10:15:03 +00:00
71 changed files with 593 additions and 439 deletions

View File

@@ -40,6 +40,27 @@ Documentation: https://sasjs.github.io/core.github.io/files.html
- X command enabled
- Prefixes: _mmw_,_mmu_,_mmx_
**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.
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:
```
/* compile the lua module */
%ml_yourmodule()
/* Execute. Do not use the restart keyword! */
proc lua;
submit;
print(yourStuff);
endsubmit;
run;
```
- X command enabled
- Prefixes: _mmw_,_mmu_,_mmx_
# 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:
@@ -72,6 +93,7 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
- _mm_ for metadata macros (interface with the metadata server).
- _mmx_ for macros that use metadata and 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
- unix style line endings (lf)
@@ -91,7 +113,25 @@ The **Macro Core** documentation is created using [doxygen](http://www.doxygen.n
- version. The EARLIEST SAS version in which this macro is known to work.
- author. Author name, contact details optional
All macros must be commented in the doxygen format, to enable the [online documentation](https://sasjs.github.io/core.github.io/).
All macros must be commented in the doxygen format, to enable the [online documentation](https://core.sasjs.io).
### Dependencies
SAS code can contain one of two types of dependency - SAS Macros, and SAS Programs. When compiling projects using the [SASjs CLI](https://cli.sasjs.io) the doxygen header is scanned for ` @li` items under the following headers:
```
<h4> SAS Macros </h4>
@li mf_nobs.sas
@li mm_assignlib.sas
<h4> SAS Programs </h4>
@li somefile.ddl SOMEFREF
@li someprogram.sas FREFTWO
```
The CLI can then extract all the dependencies and insert as precode (SAS Macros) or in a temp engine fileref (SAS Programs) when creating SAS Jobs and Services.
When contributing to this library, it is therefore important to ensure that all dependencies are listed in the header in this format.
## Coding Standards
@@ -102,6 +142,7 @@ All macros must be commented in the doxygen format, to enable the [online docume
- Mandatory parameters should be positional, all optional parameters should be keyword (var=) style.
- All dataset references must be 2 level (eg `work.blah`, not `blah`). This is to avoid contention when options [DATASTMTCHK](https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000279064.htm)=ALLKEYWORDS is in effect.
- Avoid naming collisions! All macro variables should be local scope. Use system generated work tables where possible - eg `data ; set sashelp.class; run; data &output; set &syslast; run;`
- If you have a long-running SQL query, the use of a `quit;` statement is recommended in order to benefit from the timing statistics.
# General Notes

416
all.sas
View File

@@ -199,7 +199,7 @@ options noquotelenmax;
@return output returns 1 or 0 (or -1 if not found)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@@ -270,7 +270,7 @@ options noquotelenmax;
%put %mf_existVarList(sashelp.class, age sex name dummyvar)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_abort.sas
@param libds 2 part dataset or view reference
@@ -522,7 +522,7 @@ options noquotelenmax;
@param switch the param for which to return a platform specific variable
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_mval.sas
@li mf_trimstr.sas
@@ -807,7 +807,7 @@ options noquotelenmax;
%put %mf_getvalue(sashelp.class,name,filter=%quote(age=15));
%put %mf_getvalue(sashelp.class,name);
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getattrn.sas
@param libds dataset to query
@@ -1324,7 +1324,7 @@ Usage:
%put Number of observations=%mf_nobs(sashelp.class);
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getattrn.sas
@param libds library.dataset
@@ -1351,7 +1351,7 @@ Usage:
%put %mf_trimstr(/blah/,h); * /blah/;
%put %mf_trimstr(/blah/,h/);* /bla;
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param basestr The string to be modified
@@ -1422,7 +1422,7 @@ Usage:
Returns:
> 1
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_abort.sas
@param verifyvars space separated list of macro variable names
@@ -1830,7 +1830,7 @@ Usage:
@param outds= a table containing the create statements (create_statement column)
@param execute= `YES|NO` - default is NO. To actually create, use YES.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@version 9.2
@author Allan Bowe
@@ -1900,7 +1900,7 @@ Usage:
;;;;
%mp_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001,replace=YES)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mm_createwebservice.sas
@li mv_createwebservice.sas
@@ -1986,7 +1986,7 @@ Usage:
@version 9.2
@author Allan Bowe
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_existds.sas
@@ -2375,7 +2375,7 @@ run;
create view view2 as select * from sashelp.class;
%mp_dropmembers(list=data1 view2)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_isblank.sas
@@ -2725,7 +2725,7 @@ run;
@param ds= The target dataset. Leave blank (default) for all datasets.
@param outds the output dataset
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@version 9.2
@author Allan Bowe
@@ -3103,7 +3103,7 @@ run;
proc sql; describe table &syslast;
%mp_getddl(work,test,flavour=tsql,showlog=YES)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_getconstraints.sas
@param lib libref of the library to create DDL for. Should be assigned.
@@ -3460,7 +3460,7 @@ run;
@param libds Two part dataset (or view) reference.
@param outds= The output dataset to create
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getvarlist.sas
@li mf_getvartype.sas
@li mf_getvarformat.sas
@@ -3532,7 +3532,7 @@ create table &outds (rename=(
@param min_rows= The minimum number of rows a table should have in order to try
and guess the PK. Default=5.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getvarlist.sas
@li mf_getuniquename.sas
@li mf_nobs.sas
@@ -3985,7 +3985,7 @@ create table &outds (rename=(
%mp_lib2cards(lib=sashelp
, outloc= C:\temp )
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_mkdir.sas
@li mp_ds2cards.sas
@@ -4080,16 +4080,16 @@ select distinct lowcase(memname)
data example;
set sashelp.class;
calc_var=_n_*3;
* initialise hash and save from PDV ;
%* initialise hash and save from PDV ;
%mp_prevobs(INIT,history=2)
if _n_ =10 then do;
* fetch previous but 1 record;
%* fetch previous but 1 record;
%mp_prevobs(FETCH,-2)
put _n_= name= age= calc_var=;
* fetch previous record;
%* fetch previous record;
%mp_prevobs(FETCH,-1)
put _n_= name= age= calc_var=;
* reinstate current record ;
%* reinstate current record ;
%mp_prevobs(FETCH,0)
put _n_= name= age= calc_var=;
end;
@@ -4420,7 +4420,7 @@ proc sort; by descending sumcols memname libname; run;
@param outobs= set to a positive integer to restrict the number of observations
@param filter_text= add a (valid) filter clause to further filter the results
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getvarlist.sas
@li mf_getvartype.sas
@li mf_mkdir.sas
@@ -4518,7 +4518,7 @@ proc sql
%mp_setkeyvalue(someindex,22,type=N)
%mp_setkeyvalue(somenewindex,somevalue)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_existds.sas
@param key Provide a key on which to perform the lookup
@@ -4646,7 +4646,7 @@ proc sql
%mp_streamfile(contenttype=csv,inloc=/some/where.txt,outname=myfile.txt)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mp_binarycopy.sas
@@ -4771,7 +4771,7 @@ proc sql
@param size= (0.1) The size in GB of the table to create
@param outds= (WORK.RESULTS) The output dataset to be created.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getuniquename.sas
@li mf_existds.sas
@@ -4893,7 +4893,7 @@ run;
%mp_unzip(ziploc="/some/file.zip",outdir=/some/folder)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_mkdir.sas
@li mf_getuniquefileref.sas
@@ -4964,7 +4964,7 @@ run;
@param var The variable to modify
@param len The new length to apply
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_existds.sas
@li mp_abort.sas
@li mf_existvar.sas
@@ -5051,7 +5051,7 @@ alter table &libds modify &var char(&len);
be sure that _debug is not set (else the SPWA will send non zipped content
as well).
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_dirlist.sas
@param in= unquoted filepath, dataset of files or directory to zip
@@ -5228,7 +5228,7 @@ filename __us2grp clear;
disconnect from MyAlias;
quit;
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getengine.sas
@li mp_abort.sas
@@ -5676,7 +5676,7 @@ run;
%mm_assignlib(SOMEREF)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@param libref the libref (not name) of the metadata library
@@ -5704,6 +5704,7 @@ run;
rc=metadata_getattr(liburi,"Name",LibName);
/* now try and assign it */
if libname("&libref",,'meta',cats('liburi="',liburi,'";')) ne 0 then do;
putlog "&libref could not be assigned";
call symputx('msg',sysmsg(),'l');
if "&mabort"='HARD' then call symputx('mp_abort',1,'l');
end;
@@ -5757,7 +5758,7 @@ run;
@warning application components do not get deleted when removing the container folder! be sure you have the administrative priviliges to remove this kind of metadata from the SMC plugin (or be ready to do to so programmatically).
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_verifymacvars.sas
@@ -5912,7 +5913,7 @@ run;
%mm_createdataset(tableuri=G5X8AFW1.BE00015Y)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_getlibs.sas
@li mm_gettables.sas
@li mm_getcols.sas
@@ -5988,7 +5989,7 @@ run;
%mm_createdocument(tree=/User Folders/sasdemo
,name=MyNote)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_verifymacvars.sas
@@ -6277,7 +6278,7 @@ run;
,directory=/tmp/tests
,mDebug=1)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_verifymacvars.sas
@li mm_createfolder.sas
@@ -6618,7 +6619,7 @@ filename &frefout temp;
,Server=SASApp
,stptype=2)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_nobs.sas
@li mf_verifymacvars.sas
@li mm_getdirectories.sas
@@ -6991,7 +6992,7 @@ Usage:
;;;;
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001,replace=YES)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_createstp.sas
@li mf_getuser.sas
@li mm_createfolder.sas
@@ -7382,7 +7383,7 @@ run;
%mm_createdocument(tree=/User Folders/&sysuserid,name=MyNote)
%mm_deletedocument(target=/User Folders/&sysuserid/MyNote)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param target= full path to the document being deleted
@@ -7452,7 +7453,7 @@ run;
%mm_deletestp(target=/some/meta/path/myStoredProcess)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param target= full path to the STP being deleted
@@ -7522,7 +7523,7 @@ run;
@param outds= the ONE LEVEL work dataset to create
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_getobjects.sas
@li mf_getuniquefileref.sas
@li mm_getdetails.sas
@@ -7812,7 +7813,7 @@ run;
,outref=/some/unquoted/filename.ext
)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@param tree= The metadata path of the document
@@ -7961,7 +7962,7 @@ filename __outdoc clear;
@param outds= the dataset to create that contains the list of directories
@param mDebug= set to 1 to show debug messages in the log
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@version 9.4
@author Allan Bowe
@@ -8112,17 +8113,15 @@ run;
blank to return all groups.
Usage:
- all groups
%mm_getGroups()
- all groups: `%mm_getGroups()`
- all groups for a particular user
%mm_getgroups(user=&sysuserid)
- all groups for a particular user: `%mm_getgroups(user=&sysuserid)`
@param user= the metadata user to return groups for. Leave blank for all
@param [in] user= the metadata user to return groups for. Leave blank for all
groups.
@param outds= the dataset to create that contains the list of groups
@param repo= the metadata repository that contains the user/group information
@param mDebug= set to 1 to show debug messages in the log
@param [in] repo= the metadata repository that contains the user/group information
@param [in] mDebug= set to 1 to show debug messages in the log
@param [out] outds= the dataset to create that contains the list of groups
@returns outds dataset containing all groups in a column named "metagroup"
- groupuri
@@ -8570,9 +8569,9 @@ libname _XML_ clear;
Usage:
%mm_getroles()
%mm_getroles()
@param outds the dataset to create that contains the list of roles
@param [out] outds the dataset to create that contains the list of roles
@returns outds dataset containing all roles, with the following columns:
- uri
@@ -8648,7 +8647,7 @@ libname _XML_ clear;
filename __mc2 clear;
libname __mc3 clear;
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_getrepos.sas
@version 9.3
@@ -8887,7 +8886,7 @@ filename __outdoc clear;
%mm_getstps(tree=/My Folder/My STPs, name=My STP)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_gettree.sas
@param tree= the metadata folder location in which to search. Leave blank
@@ -9555,7 +9554,7 @@ filename __shake clear;
./mmscript.sh "myuser" "mypass"
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_loc.sas
@li mm_tree.sas
@li mf_getuniquefileref.sas
@@ -9675,7 +9674,7 @@ run;
Table
,outds=morestuff)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getquotedstr.sas
@li mm_getpublictypes.sas
@li mf_isblank.sas
@@ -10056,7 +10055,7 @@ run;
%mm_updatestpservertype(target=/some/meta/path/myStoredProcess
,type=WKS)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param target= full path to the STP being deleted
@param type= Either WKS or STP depending on whether Workspace or Stored Process
@@ -10412,7 +10411,7 @@ run;
%mmx_deletemetafolder(loc=/some/meta/folder,user=sasdemo,pass=mars345)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_loc.sas
@param loc= the metadata folder to delete
@@ -10467,7 +10466,7 @@ Usage:
,outspkpath=%str(/tmp)
)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_loc.sas
@li mm_tree.sas
@li mf_getuniquefileref.sas
@@ -10549,7 +10548,7 @@ run;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@@ -10712,7 +10711,7 @@ options noquotelenmax;
To minimise postgres requests, output json is stored in a temporary file
and then sent to _webout in one go at the end.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mv_createfolder.sas
@li mf_getuniquelibref.sas
@@ -11362,7 +11361,7 @@ run;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -11489,8 +11488,8 @@ filename &fname1a clear;
libname &libref1a clear;
%mend;/**
@file mv_deletejes.sas
@brief Creates a job execution service if it does not already exist
@file
@brief Deletes a Viya Job, if it exists
@details If not executed in Studio 5+ will expect oauth token in a global
macro variable (default ACCESS_TOKEN).
@@ -11511,7 +11510,7 @@ libname &libref1a clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -11655,7 +11654,7 @@ libname &libref1a clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -11783,7 +11782,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mv_tokenrefresh.sas
**/
@@ -11814,7 +11813,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mv_registerclient.sas
**/
@@ -11862,7 +11861,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -11948,7 +11947,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12081,7 +12080,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12185,7 +12184,7 @@ filename &fname1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12248,14 +12247,164 @@ run;
filename &fname1 clear;
libname &libref1 clear;
%mend; /**
%mend;/**
@file
@brief Extract the source code from a SAS Viya Job
@details Extracts the SAS code from a Job into a fileref or physical file.
Example:
%mv_getjobcode(
path=/Public/jobs
,name=some_job
,outfile=/tmp/some_job.sas
)
@param [in] access_token_var= The global macro variable to contain the access token
@param [in] grant_type= valid values:
* password
* authorization_code
* detect - will check if access_token exists, if not will use sas_services if
a SASStudioV session else authorization_code. Default option.
* sas_services - will use oauth_bearer=sas_services
@param [in] path= The SAS Drive path of the job
@param [in] name= The name of the job
@param [out] outref= A fileref to which to write the source code
@param [out] outfile= A file to which to write the source code
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@li mv_getfoldermembers.sas
@li ml_json.sas
**/
%macro mv_getjobcode(outref=0,outfile=0
,name=0,path=0
,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN
,grant_type=sas_services
);
%local oauth_bearer;
%if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
%else %let grant_type=sas_services;
%end;
%if &grant_type=sas_services %then %do;
%let oauth_bearer=oauth_bearer=sas_services;
%let &access_token_var=;
%end;
%put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services
)
,mac=&sysmacroname
,msg=%str(Invalid value for grant_type: &grant_type)
)
%mp_abort(iftrue=("&path"="0")
,mac=&sysmacroname
,msg=%str(Job Path not provided)
)
%mp_abort(iftrue=("&name"="0")
,mac=&sysmacroname
,msg=%str(Job Name not provided)
)
%mp_abort(iftrue=("&outfile"="0" and "&outref"="0")
,mac=&sysmacroname
,msg=%str(Output destination (file or fileref) must be provided)
)
options noquotelenmax;
%local base_uri; /* location of rest apis */
%let base_uri=%mf_getplatform(VIYARESTAPI);
data;run;
%local foldermembers;
%let foldermembers=&syslast;
%mv_getfoldermembers(root=&path
,access_token_var=&access_token_var
,grant_type=&grant_type
,outds=&foldermembers
)
%local joburi;
%let joburi=0;
data _null_;
set &foldermembers;
if name="&name" and uri=:'/jobDefinitions/definitions'
then call symputx('joburi',uri);
run;
%mp_abort(iftrue=("&joburi"="0")
,mac=&sysmacroname
,msg=%str(Job &path/&name not found)
)
/* prepare request*/
%local fname1;
%let fname1=%mf_getuniquefileref();
proc http method='GET' out=&fname1 &oauth_bearer
url="&base_uri&joburi";
headers "Accept"="application/vnd.sas.job.definition+json"
%if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var"
%end;
;
run;
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
%do;
data _null_;infile &fname1;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
%end;
%local fname2 fname3 fpath1 fpath2 fpath3;
%let fname2=%mf_getuniquefileref();
%let fname3=%mf_getuniquefileref();
%let fpath1=%sysfunc(pathname(&fname1));
%let fpath2=%sysfunc(pathname(&fname2));
%let fpath3=%sysfunc(pathname(&fname2));
/* compile the lua JSON module */
%ml_json()
/* read using LUA - this allows the code to be of any length */
data _null_;
file "&fpath3..lua";
put '
infile = io.open (sas.symget("fpath1"), "r")
outfile = io.open (sas.symget("fpath2"), "w")
io.input(infile)
local resp=json2sas.decode(io.read())
local job=resp["code"]
outfile:write(job)
io.close(infile)
io.close(outfile)
';
run;
%inc "&fpath3..lua";
/* export to desired destination */
data _null_;
%if &outref=0 %then %do;
file "&outfile" lrecl=32767;
%end;
%else %do;
file &outref;
%end;
infile &fname2;
input;
put _infile_;
run;
filename &fname1 clear;
filename &fname2 clear;
%mend;
/**
@file mv_getrefreshtoken.sas
@brief deprecated - replaced by mv_tokenauth.sas
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mv_tokenauth.sas
**/
@@ -12304,7 +12453,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12422,7 +12571,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12533,7 +12682,7 @@ libname &libref1 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12709,7 +12858,7 @@ libname &libref;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -12932,7 +13081,7 @@ libname &libref clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -13074,7 +13223,7 @@ filename &fref2 clear;
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@@ -13189,7 +13338,7 @@ filename &fref1 clear;
@param dslabel= value to use instead of the real name for sending to JSON
@param fmt= change to N to strip formats from output
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_jsonout.sas
@li mf_getuser.sas
@@ -13386,20 +13535,21 @@ filename &fref1 clear;
%mend;
/**
@file ml_json2sas.sas
@brief Creates the json2sas.lua file
@details Writes json2sas.lua to the work directory
@file ml_json.sas
@brief Compiles the json.lua lua file
@details Writes json.lua to the work directory
and then includes it.
Usage:
%ml_json2sas()
%ml_json()
**/
%macro ml_json2sas();
%macro ml_json();
data _null_;
file "%sysfunc(pathname(work))/json2sas.lua";
file "%sysfunc(pathname(work))/ml_json.lua";
put '-- ';
put '-- json2sas.lua (modified from json.lua) ';
put '-- json.lua (modified from json.lua) ';
put '-- ';
put '-- Copyright (c) 2019 rxi ';
put '-- ';
@@ -13422,7 +13572,7 @@ data _null_;
put '-- SOFTWARE. ';
put '-- ';
put ' ';
put 'local json2sas = { _version = "0.1.2" } ';
put 'local json = { _version = "0.1.2" } ';
put ' ';
put '------------------------------------------------------------------------------- ';
put '-- Encode ';
@@ -13522,7 +13672,7 @@ data _null_;
put ' error("unexpected type ''" .. t .. "''") ';
put 'end ';
put ' ';
put 'function json2sas.encode(val) ';
put 'function json.encode(val) ';
put ' return ( encode(val) ) ';
put 'end ';
put ' ';
@@ -13756,7 +13906,7 @@ data _null_;
put ' decode_error(str, idx, "unexpected character ''" .. chr .. "''") ';
put 'end ';
put ' ';
put 'function json2sas.decode(str) ';
put 'function json.decode(str) ';
put ' if type(str) ~= "string" then ';
put ' error("expected argument of type string, got " .. type(str)) ';
put ' end ';
@@ -13768,90 +13918,8 @@ data _null_;
put ' return res ';
put 'end ';
put ' ';
put '-- convert macro variable array into one variable and decode ';
put 'function json2sas.go(macvar) ';
put ' local x=1 ';
put ' local cnt=0 ';
put ' local mac=sas.symget(macvar..''0'') ';
put ' local newstr='''' ';
put ' if mac and mac ~= '''' then ';
put ' cnt=mac ';
put ' for x=1,cnt,1 do ';
put ' mac=sas.symget(macvar..x) ';
put ' if mac and mac ~= '''' then ';
put ' newstr=newstr..mac ';
put ' else ';
put ' return print(macvar..x..'' NOT FOUND!!'') ';
put ' end ';
put ' end ';
put ' else ';
put ' return print(macvar..''0 NOT FOUND!!'') ';
put ' end ';
put ' -- print(''mac:''..mac..''cnt:''..cnt..''newstr''..newstr) ';
put ' local oneVar=json2sas.decode(newstr) ';
put ' local jsdata=oneVar["data"] ';
put ' local meta={} ';
put ' local attrs={} ';
put ' for tablename, data in pairs(jsdata) do -- each table ';
put ' print("Processing table: "..tablename) ';
put ' attrs[tablename]={} ';
put ' for k, v in ipairs(data) do -- each row ';
put ' if(k==1) then -- column names ';
put ' for a, b in pairs(v) do ';
put ' attrs[tablename][a]={} ';
put ' attrs[tablename][a]["name"]=b ';
put ' end ';
put ' elseif(k==2) then -- get types ';
put ' for a, b in pairs(v) do ';
put ' if type(b)==''number'' then ';
put ' attrs[tablename][a]["type"]="N" ';
put ' attrs[tablename][a]["length"]=8 ';
put ' else ';
put ' attrs[tablename][a]["type"]="C" ';
put ' attrs[tablename][a]["length"]=string.len(b) ';
put ' end ';
put ' end ';
put ' else --update lengths ';
put ' for a, b in pairs(v) do ';
put ' if (type(b)==''string'' and string.len(b)>attrs[tablename][a]["length"]) ';
put ' then ';
put ' attrs[tablename][a]["length"]=string.len(b) ';
put ' end ';
put ' end ';
put ' end ';
put ' end ';
put ' print(json2sas.encode(attrs[tablename])) -- show results ';
put ' ';
put ' -- Now create the SAS table ';
put ' sas.new_table("work."..tablename,attrs[tablename]) ';
put ' local dsid=sas.open("work."..tablename, "u") ';
put ' for k, v in ipairs(data) do ';
put ' if k>1 then ';
put ' sas.append(dsid) ';
put ' for a, b in pairs(v) do ';
put ' sas.put_value(dsid, attrs[tablename][a]["name"], b) ';
put ' end ';
put ' sas.update(dsid) ';
put ' end ';
put ' end ';
put ' sas.close(dsid) ';
put ' end ';
put ' return json2sas.decode(newstr) ';
put 'end ';
put ' ';
put ' ';
put 'function quote(str) ';
put ' return sas.quote(str) ';
put 'end ';
put 'function sasvar(str) ';
put ' print("processing: "..str) ';
put ' print(sas.symexist(str)) ';
put ' if sas.symexist(str)==1 then ';
put ' return quote(str)..'':''..quote(sas.symget(str))..'','' ';
put ' end ';
put ' return '''' ';
put 'end ';
put ' ';
put 'return json2sas ';
put 'return json ';
run;
%mend;
%inc "%sysfunc(pathname(work))/ml_json.lua";

View File

@@ -13,7 +13,7 @@
@return output returns 1 or 0 (or -1 if not found)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getplatform.sas

View File

@@ -6,7 +6,7 @@
%put %mf_existVarList(sashelp.class, age sex name dummyvar)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_abort.sas
@param libds 2 part dataset or view reference

View File

@@ -10,7 +10,7 @@
@param switch the param for which to return a platform specific variable
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_mval.sas
@li mf_trimstr.sas

View File

@@ -7,7 +7,7 @@
%put %mf_getvalue(sashelp.class,name,filter=%quote(age=15));
%put %mf_getvalue(sashelp.class,name);
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getattrn.sas
@param libds dataset to query

View File

@@ -6,7 +6,7 @@
%put Number of observations=%mf_nobs(sashelp.class);
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getattrn.sas
@param libds library.dataset

View File

@@ -8,7 +8,7 @@
%put %mf_trimstr(/blah/,h); * /blah/;
%put %mf_trimstr(/blah/,h/);* /bla;
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param basestr The string to be modified

View File

@@ -11,7 +11,7 @@
Returns:
> 1
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_abort.sas
@param verifyvars space separated list of macro variable names

View File

@@ -22,7 +22,7 @@
@param outds= a table containing the create statements (create_statement column)
@param execute= `YES|NO` - default is NO. To actually create, use YES.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@version 9.2
@author Allan Bowe

View File

@@ -26,7 +26,7 @@ Usage:
;;;;
%mp_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001,replace=YES)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mm_createwebservice.sas
@li mv_createwebservice.sas

View File

@@ -29,7 +29,7 @@
@version 9.2
@author Allan Bowe
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_existds.sas

View File

@@ -9,7 +9,7 @@
create view view2 as select * from sashelp.class;
%mp_dropmembers(list=data1 view2)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_isblank.sas

View File

@@ -21,7 +21,7 @@
@param ds= The target dataset. Leave blank (default) for all datasets.
@param outds the output dataset
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@version 9.2
@author Allan Bowe

View File

@@ -15,7 +15,7 @@
proc sql; describe table &syslast;
%mp_getddl(work,test,flavour=tsql,showlog=YES)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_getconstraints.sas
@param lib libref of the library to create DDL for. Should be assigned.

View File

@@ -21,7 +21,7 @@
@param libds Two part dataset (or view) reference.
@param outds= The output dataset to create
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getvarlist.sas
@li mf_getvartype.sas
@li mf_getvarformat.sas

View File

@@ -22,7 +22,7 @@
@param min_rows= The minimum number of rows a table should have in order to try
and guess the PK. Default=5.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getvarlist.sas
@li mf_getuniquename.sas
@li mf_nobs.sas

View File

@@ -8,7 +8,7 @@
%mp_lib2cards(lib=sashelp
, outloc= C:\temp )
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_mkdir.sas
@li mp_ds2cards.sas

View File

@@ -12,16 +12,16 @@
data example;
set sashelp.class;
calc_var=_n_*3;
* initialise hash and save from PDV ;
%* initialise hash and save from PDV ;
%mp_prevobs(INIT,history=2)
if _n_ =10 then do;
* fetch previous but 1 record;
%* fetch previous but 1 record;
%mp_prevobs(FETCH,-2)
put _n_= name= age= calc_var=;
* fetch previous record;
%* fetch previous record;
%mp_prevobs(FETCH,-1)
put _n_= name= age= calc_var=;
* reinstate current record ;
%* reinstate current record ;
%mp_prevobs(FETCH,0)
put _n_= name= age= calc_var=;
end;

View File

@@ -25,7 +25,7 @@
@param outobs= set to a positive integer to restrict the number of observations
@param filter_text= add a (valid) filter clause to further filter the results
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getvarlist.sas
@li mf_getvartype.sas
@li mf_mkdir.sas

View File

@@ -6,7 +6,7 @@
%mp_setkeyvalue(someindex,22,type=N)
%mp_setkeyvalue(somenewindex,somevalue)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_existds.sas
@param key Provide a key on which to perform the lookup

View File

@@ -11,7 +11,7 @@
%mp_streamfile(contenttype=csv,inloc=/some/where.txt,outname=myfile.txt)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getplatform.sas
@li mp_binarycopy.sas

View File

@@ -0,0 +1,59 @@
/**
@file mp_testwritespeedlibrary.sas
@brief Tests the write speed of a new table in a SAS library
@details Will create a new table of a certain size in an
existing SAS library. The table will have one column,
and will be subsequently deleted.
%mp_testwritespeedlibrary(
lib=work
,size=0.5
,outds=work.results
)
@param lib= (WORK) The library in which to create the table
@param size= (0.1) The size in GB of the table to create
@param outds= (WORK.RESULTS) The output dataset to be created.
<h4> SAS Macros </h4>
@li mf_getuniquename.sas
@li mf_existds.sas
@version 9.4
@author Allan Bowe
**/
%macro mp_testwritespeedlibrary(lib=WORK
,outds=work.results
,size=0.1
)/*/STORE SOURCE*/;
%local ds start;
/* find an unused, unique name for the new table */
%let ds=%mf_getuniquename();
%do %until(%mf_existds(&lib..&ds)=0);
%let ds=%mf_getuniquename();
%end;
%let start=%sysfunc(datetime());
data &lib..&ds(compress=no keep=x);
header=128*1024;
size=(1073741824/8 * &size) - header;
do x=1 to size;
output;
end;
run;
proc sql;
drop table &lib..&ds;
data &outds;
lib="&lib";
start_dttm=put(&start,datetime19.);
end_dttm=put(datetime(),datetime19.);
duration_seconds=end_dttm-start_dttm;
run;
%mend;

View File

@@ -12,7 +12,7 @@
%mp_unzip(ziploc="/some/file.zip",outdir=/some/folder)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_mkdir.sas
@li mf_getuniquefileref.sas

View File

@@ -18,7 +18,7 @@
@param var The variable to modify
@param len The new length to apply
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_existds.sas
@li mp_abort.sas
@li mf_existvar.sas

View File

@@ -12,7 +12,7 @@
be sure that _debug is not set (else the SPWA will send non zipped content
as well).
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_dirlist.sas
@param in= unquoted filepath, dataset of files or directory to zip

View File

@@ -9,19 +9,21 @@ for file in files:
ml = open('lua/' + name + '.sas', "w")
ml.write("/**\n")
ml.write(" @file " + name + '.sas\n')
ml.write(" @brief Creates the " + basename + " file\n")
ml.write(" @brief Compiles the " + basename + " lua file\n")
ml.write(" @details Writes " + basename + " to the work directory\n")
ml.write(" and then includes it.\n")
ml.write(" Usage:\n\n")
ml.write(" %" + name + "()\n\n")
ml.write("**/\n\n")
ml.write("%macro " + name + "();\n")
ml.write("data _null_;\n")
ml.write(" file \"%sysfunc(pathname(work))/" + basename + "\";\n")
ml.write(" file \"%sysfunc(pathname(work))/" + name + ".lua\";\n")
with open(file) as infile:
for line in infile:
ml.write(" put '" + line.rstrip().replace("'","''") + " ';\n")
ml.write("run;\n")
ml.write("%mend;\n")
ml.write("%mend;\n\n")
ml.write("%inc \"%sysfunc(pathname(work))/" + name + ".lua\";\n")
ml.close()
# prepare web files

View File

@@ -1,5 +1,5 @@
--
-- json2sas.lua (modified from json.lua)
-- json.lua (modified from json.lua)
--
-- Copyright (c) 2019 rxi
--
@@ -22,7 +22,7 @@
-- SOFTWARE.
--
local json2sas = { _version = "0.1.2" }
local json = { _version = "0.1.2" }
-------------------------------------------------------------------------------
-- Encode
@@ -122,7 +122,7 @@ encode = function(val, stack)
error("unexpected type '" .. t .. "'")
end
function json2sas.encode(val)
function json.encode(val)
return ( encode(val) )
end
@@ -356,7 +356,7 @@ parse = function(str, idx)
decode_error(str, idx, "unexpected character '" .. chr .. "'")
end
function json2sas.decode(str)
function json.decode(str)
if type(str) ~= "string" then
error("expected argument of type string, got " .. type(str))
end
@@ -368,88 +368,4 @@ function json2sas.decode(str)
return res
end
-- convert macro variable array into one variable and decode
function json2sas.go(macvar)
local x=1
local cnt=0
local mac=sas.symget(macvar..'0')
local newstr=''
if mac and mac ~= '' then
cnt=mac
for x=1,cnt,1 do
mac=sas.symget(macvar..x)
if mac and mac ~= '' then
newstr=newstr..mac
else
return print(macvar..x..' NOT FOUND!!')
end
end
else
return print(macvar..'0 NOT FOUND!!')
end
-- print('mac:'..mac..'cnt:'..cnt..'newstr'..newstr)
local oneVar=json2sas.decode(newstr)
local jsdata=oneVar["data"]
local meta={}
local attrs={}
for tablename, data in pairs(jsdata) do -- each table
print("Processing table: "..tablename)
attrs[tablename]={}
for k, v in ipairs(data) do -- each row
if(k==1) then -- column names
for a, b in pairs(v) do
attrs[tablename][a]={}
attrs[tablename][a]["name"]=b
end
elseif(k==2) then -- get types
for a, b in pairs(v) do
if type(b)=='number' then
attrs[tablename][a]["type"]="N"
attrs[tablename][a]["length"]=8
else
attrs[tablename][a]["type"]="C"
attrs[tablename][a]["length"]=string.len(b)
end
end
else --update lengths
for a, b in pairs(v) do
if (type(b)=='string' and string.len(b)>attrs[tablename][a]["length"])
then
attrs[tablename][a]["length"]=string.len(b)
end
end
end
end
print(json2sas.encode(attrs[tablename])) -- show results
-- Now create the SAS table
sas.new_table("work."..tablename,attrs[tablename])
local dsid=sas.open("work."..tablename, "u")
for k, v in ipairs(data) do
if k>1 then
sas.append(dsid)
for a, b in pairs(v) do
sas.put_value(dsid, attrs[tablename][a]["name"], b)
end
sas.update(dsid)
end
end
sas.close(dsid)
end
return json2sas.decode(newstr)
end
function quote(str)
return sas.quote(str)
end
function sasvar(str)
print("processing: "..str)
print(sas.symexist(str))
if sas.symexist(str)==1 then
return quote(str)..':'..quote(sas.symget(str))..','
end
return ''
end
return json2sas
return json

View File

@@ -1,18 +1,19 @@
/**
@file ml_json2sas.sas
@brief Creates the json2sas.lua file
@details Writes json2sas.lua to the work directory
@file ml_json.sas
@brief Compiles the json.lua lua file
@details Writes json.lua to the work directory
and then includes it.
Usage:
%ml_json2sas()
%ml_json()
**/
%macro ml_json2sas();
%macro ml_json();
data _null_;
file "%sysfunc(pathname(work))/json2sas.lua";
file "%sysfunc(pathname(work))/ml_json.lua";
put '-- ';
put '-- json2sas.lua (modified from json.lua) ';
put '-- json.lua (modified from json.lua) ';
put '-- ';
put '-- Copyright (c) 2019 rxi ';
put '-- ';
@@ -35,7 +36,7 @@ data _null_;
put '-- SOFTWARE. ';
put '-- ';
put ' ';
put 'local json2sas = { _version = "0.1.2" } ';
put 'local json = { _version = "0.1.2" } ';
put ' ';
put '------------------------------------------------------------------------------- ';
put '-- Encode ';
@@ -135,7 +136,7 @@ data _null_;
put ' error("unexpected type ''" .. t .. "''") ';
put 'end ';
put ' ';
put 'function json2sas.encode(val) ';
put 'function json.encode(val) ';
put ' return ( encode(val) ) ';
put 'end ';
put ' ';
@@ -369,7 +370,7 @@ data _null_;
put ' decode_error(str, idx, "unexpected character ''" .. chr .. "''") ';
put 'end ';
put ' ';
put 'function json2sas.decode(str) ';
put 'function json.decode(str) ';
put ' if type(str) ~= "string" then ';
put ' error("expected argument of type string, got " .. type(str)) ';
put ' end ';
@@ -381,90 +382,8 @@ data _null_;
put ' return res ';
put 'end ';
put ' ';
put '-- convert macro variable array into one variable and decode ';
put 'function json2sas.go(macvar) ';
put ' local x=1 ';
put ' local cnt=0 ';
put ' local mac=sas.symget(macvar..''0'') ';
put ' local newstr='''' ';
put ' if mac and mac ~= '''' then ';
put ' cnt=mac ';
put ' for x=1,cnt,1 do ';
put ' mac=sas.symget(macvar..x) ';
put ' if mac and mac ~= '''' then ';
put ' newstr=newstr..mac ';
put ' else ';
put ' return print(macvar..x..'' NOT FOUND!!'') ';
put ' end ';
put ' end ';
put ' else ';
put ' return print(macvar..''0 NOT FOUND!!'') ';
put ' end ';
put ' -- print(''mac:''..mac..''cnt:''..cnt..''newstr''..newstr) ';
put ' local oneVar=json2sas.decode(newstr) ';
put ' local jsdata=oneVar["data"] ';
put ' local meta={} ';
put ' local attrs={} ';
put ' for tablename, data in pairs(jsdata) do -- each table ';
put ' print("Processing table: "..tablename) ';
put ' attrs[tablename]={} ';
put ' for k, v in ipairs(data) do -- each row ';
put ' if(k==1) then -- column names ';
put ' for a, b in pairs(v) do ';
put ' attrs[tablename][a]={} ';
put ' attrs[tablename][a]["name"]=b ';
put ' end ';
put ' elseif(k==2) then -- get types ';
put ' for a, b in pairs(v) do ';
put ' if type(b)==''number'' then ';
put ' attrs[tablename][a]["type"]="N" ';
put ' attrs[tablename][a]["length"]=8 ';
put ' else ';
put ' attrs[tablename][a]["type"]="C" ';
put ' attrs[tablename][a]["length"]=string.len(b) ';
put ' end ';
put ' end ';
put ' else --update lengths ';
put ' for a, b in pairs(v) do ';
put ' if (type(b)==''string'' and string.len(b)>attrs[tablename][a]["length"]) ';
put ' then ';
put ' attrs[tablename][a]["length"]=string.len(b) ';
put ' end ';
put ' end ';
put ' end ';
put ' end ';
put ' print(json2sas.encode(attrs[tablename])) -- show results ';
put ' ';
put ' -- Now create the SAS table ';
put ' sas.new_table("work."..tablename,attrs[tablename]) ';
put ' local dsid=sas.open("work."..tablename, "u") ';
put ' for k, v in ipairs(data) do ';
put ' if k>1 then ';
put ' sas.append(dsid) ';
put ' for a, b in pairs(v) do ';
put ' sas.put_value(dsid, attrs[tablename][a]["name"], b) ';
put ' end ';
put ' sas.update(dsid) ';
put ' end ';
put ' end ';
put ' sas.close(dsid) ';
put ' end ';
put ' return json2sas.decode(newstr) ';
put 'end ';
put ' ';
put ' ';
put 'function quote(str) ';
put ' return sas.quote(str) ';
put 'end ';
put 'function sasvar(str) ';
put ' print("processing: "..str) ';
put ' print(sas.symexist(str)) ';
put ' if sas.symexist(str)==1 then ';
put ' return quote(str)..'':''..quote(sas.symget(str))..'','' ';
put ' end ';
put ' return '''' ';
put 'end ';
put ' ';
put 'return json2sas ';
put 'return json ';
run;
%mend;
%inc "%sysfunc(pathname(work))/ml_json.lua";

View File

@@ -14,7 +14,7 @@
disconnect from MyAlias;
quit;
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getengine.sas
@li mp_abort.sas

View File

@@ -10,7 +10,7 @@
%mm_assignlib(SOMEREF)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@param libref the libref (not name) of the metadata library
@@ -38,6 +38,7 @@
rc=metadata_getattr(liburi,"Name",LibName);
/* now try and assign it */
if libname("&libref",,'meta',cats('liburi="',liburi,'";')) ne 0 then do;
putlog "&libref could not be assigned";
call symputx('msg',sysmsg(),'l');
if "&mabort"='HARD' then call symputx('mp_abort',1,'l');
end;

View File

@@ -15,7 +15,7 @@
@warning application components do not get deleted when removing the container folder! be sure you have the administrative priviliges to remove this kind of metadata from the SMC plugin (or be ready to do to so programmatically).
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_verifymacvars.sas

View File

@@ -18,7 +18,7 @@
%mm_createdataset(tableuri=G5X8AFW1.BE00015Y)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_getlibs.sas
@li mm_gettables.sas
@li mm_getcols.sas

View File

@@ -12,7 +12,7 @@
%mm_createdocument(tree=/User Folders/sasdemo
,name=MyNote)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_verifymacvars.sas

View File

@@ -19,7 +19,7 @@
,directory=/tmp/tests
,mDebug=1)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_verifymacvars.sas
@li mm_createfolder.sas

View File

@@ -39,7 +39,7 @@
,Server=SASApp
,stptype=2)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_nobs.sas
@li mf_verifymacvars.sas
@li mm_getdirectories.sas

View File

@@ -24,7 +24,7 @@ Usage:
;;;;
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001,replace=YES)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_createstp.sas
@li mf_getuser.sas
@li mm_createfolder.sas

View File

@@ -8,7 +8,7 @@
%mm_createdocument(tree=/User Folders/&sysuserid,name=MyNote)
%mm_deletedocument(target=/User Folders/&sysuserid/MyNote)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param target= full path to the document being deleted

View File

@@ -7,7 +7,7 @@
%mm_deletestp(target=/some/meta/path/myStoredProcess)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param target= full path to the STP being deleted

View File

@@ -7,7 +7,7 @@
@param outds= the ONE LEVEL work dataset to create
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_getobjects.sas
@li mf_getuniquefileref.sas
@li mm_getdetails.sas

View File

@@ -11,7 +11,7 @@
,outref=/some/unquoted/filename.ext
)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@param tree= The metadata path of the document

View File

@@ -14,7 +14,7 @@
@param outds= the dataset to create that contains the list of directories
@param mDebug= set to 1 to show debug messages in the log
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@version 9.4
@author Allan Bowe

View File

@@ -5,17 +5,15 @@
blank to return all groups.
Usage:
- all groups
%mm_getGroups()
- all groups: `%mm_getGroups()`
- all groups for a particular user
%mm_getgroups(user=&sysuserid)
- all groups for a particular user: `%mm_getgroups(user=&sysuserid)`
@param user= the metadata user to return groups for. Leave blank for all
@param [in] user= the metadata user to return groups for. Leave blank for all
groups.
@param outds= the dataset to create that contains the list of groups
@param repo= the metadata repository that contains the user/group information
@param mDebug= set to 1 to show debug messages in the log
@param [in] repo= the metadata repository that contains the user/group information
@param [in] mDebug= set to 1 to show debug messages in the log
@param [out] outds= the dataset to create that contains the list of groups
@returns outds dataset containing all groups in a column named "metagroup"
- groupuri

View File

@@ -5,9 +5,9 @@
Usage:
%mm_getroles()
%mm_getroles()
@param outds the dataset to create that contains the list of roles
@param [out] outds the dataset to create that contains the list of roles
@returns outds dataset containing all roles, with the following columns:
- uri

View File

@@ -14,7 +14,7 @@
filename __mc2 clear;
libname __mc3 clear;
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_getrepos.sas
@version 9.3

View File

@@ -14,7 +14,7 @@
%mm_getstps(tree=/My Folder/My STPs, name=My STP)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mm_gettree.sas
@param tree= the metadata folder location in which to search. Leave blank

View File

@@ -45,7 +45,7 @@
./mmscript.sh "myuser" "mypass"
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_loc.sas
@li mm_tree.sas
@li mf_getuniquefileref.sas

View File

@@ -46,7 +46,7 @@
Table
,outds=morestuff)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_getquotedstr.sas
@li mm_getpublictypes.sas
@li mf_isblank.sas

View File

@@ -8,7 +8,7 @@
%mm_updatestpservertype(target=/some/meta/path/myStoredProcess
,type=WKS)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@param target= full path to the STP being deleted
@param type= Either WKS or STP depending on whether Workspace or Stored Process

View File

@@ -9,7 +9,7 @@
%mmx_deletemetafolder(loc=/some/meta/folder,user=sasdemo,pass=mars345)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_loc.sas
@param loc= the metadata folder to delete

View File

@@ -25,7 +25,7 @@ Usage:
,outspkpath=%str(/tmp)
)
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mf_loc.sas
@li mm_tree.sas
@li mf_getuniquefileref.sas

View File

@@ -17,7 +17,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas

View File

@@ -29,7 +29,7 @@
To minimise postgres requests, output json is stored in a temporary file
and then sent to _webout in one go at the end.
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mv_createfolder.sas
@li mf_getuniquelibref.sas

View File

@@ -22,7 +22,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -1,6 +1,6 @@
/**
@file mv_deletejes.sas
@brief Creates a job execution service if it does not already exist
@file
@brief Deletes a Viya Job, if it exists
@details If not executed in Studio 5+ will expect oauth token in a global
macro variable (default ACCESS_TOKEN).
@@ -21,7 +21,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -18,7 +18,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -5,7 +5,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mv_tokenrefresh.sas
**/

View File

@@ -5,7 +5,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mv_registerclient.sas
**/

View File

@@ -31,7 +31,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -17,7 +17,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -32,7 +32,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -31,7 +31,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

150
viya/mv_getjobcode.sas Normal file
View File

@@ -0,0 +1,150 @@
/**
@file
@brief Extract the source code from a SAS Viya Job
@details Extracts the SAS code from a Job into a fileref or physical file.
Example:
%mv_getjobcode(
path=/Public/jobs
,name=some_job
,outfile=/tmp/some_job.sas
)
@param [in] access_token_var= The global macro variable to contain the access token
@param [in] grant_type= valid values:
* password
* authorization_code
* detect - will check if access_token exists, if not will use sas_services if
a SASStudioV session else authorization_code. Default option.
* sas_services - will use oauth_bearer=sas_services
@param [in] path= The SAS Drive path of the job
@param [in] name= The name of the job
@param [out] outref= A fileref to which to write the source code
@param [out] outfile= A file to which to write the source code
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas
@li mv_getfoldermembers.sas
@li ml_json.sas
**/
%macro mv_getjobcode(outref=0,outfile=0
,name=0,path=0
,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN
,grant_type=sas_services
);
%local oauth_bearer;
%if &grant_type=detect %then %do;
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
%else %let grant_type=sas_services;
%end;
%if &grant_type=sas_services %then %do;
%let oauth_bearer=oauth_bearer=sas_services;
%let &access_token_var=;
%end;
%put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services
)
,mac=&sysmacroname
,msg=%str(Invalid value for grant_type: &grant_type)
)
%mp_abort(iftrue=("&path"="0")
,mac=&sysmacroname
,msg=%str(Job Path not provided)
)
%mp_abort(iftrue=("&name"="0")
,mac=&sysmacroname
,msg=%str(Job Name not provided)
)
%mp_abort(iftrue=("&outfile"="0" and "&outref"="0")
,mac=&sysmacroname
,msg=%str(Output destination (file or fileref) must be provided)
)
options noquotelenmax;
%local base_uri; /* location of rest apis */
%let base_uri=%mf_getplatform(VIYARESTAPI);
data;run;
%local foldermembers;
%let foldermembers=&syslast;
%mv_getfoldermembers(root=&path
,access_token_var=&access_token_var
,grant_type=&grant_type
,outds=&foldermembers
)
%local joburi;
%let joburi=0;
data _null_;
set &foldermembers;
if name="&name" and uri=:'/jobDefinitions/definitions'
then call symputx('joburi',uri);
run;
%mp_abort(iftrue=("&joburi"="0")
,mac=&sysmacroname
,msg=%str(Job &path/&name not found)
)
/* prepare request*/
%local fname1;
%let fname1=%mf_getuniquefileref();
proc http method='GET' out=&fname1 &oauth_bearer
url="&base_uri&joburi";
headers "Accept"="application/vnd.sas.job.definition+json"
%if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var"
%end;
;
run;
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
%do;
data _null_;infile &fname1;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
)
%end;
%local fname2 fname3 fpath1 fpath2 fpath3;
%let fname2=%mf_getuniquefileref();
%let fname3=%mf_getuniquefileref();
%let fpath1=%sysfunc(pathname(&fname1));
%let fpath2=%sysfunc(pathname(&fname2));
%let fpath3=%sysfunc(pathname(&fname2));
/* compile the lua JSON module */
%ml_json()
/* read using LUA - this allows the code to be of any length */
data _null_;
file "&fpath3..lua";
put '
infile = io.open (sas.symget("fpath1"), "r")
outfile = io.open (sas.symget("fpath2"), "w")
io.input(infile)
local resp=json2sas.decode(io.read())
local job=resp["code"]
outfile:write(job)
io.close(infile)
io.close(outfile)
';
run;
%inc "&fpath3..lua";
/* export to desired destination */
data _null_;
%if &outref=0 %then %do;
file "&outfile" lrecl=32767;
%end;
%else %do;
file &outref;
%end;
infile &fname2;
input;
put _infile_;
run;
filename &fname1 clear;
filename &fname2 clear;
%mend;

View File

@@ -5,7 +5,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mv_tokenauth.sas
**/

View File

@@ -22,7 +22,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -49,7 +49,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -45,7 +45,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -54,7 +54,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -43,7 +43,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -42,7 +42,7 @@
@version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_abort.sas
@li mf_getplatform.sas
@li mf_getuniquefileref.sas

View File

@@ -27,7 +27,7 @@
@param dslabel= value to use instead of the real name for sending to JSON
@param fmt= change to N to strip formats from output
<h4> Dependencies </h4>
<h4> SAS Macros </h4>
@li mp_jsonout.sas
@li mf_getuser.sas