1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-20 17:51:19 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Allan Bowe
4c333ae7b3 feat: mp_prevobs.sas macro 2020-12-23 00:33:59 +00:00
b3a8b4323e fix: adding new mp_ds2csv macro 2020-12-16 17:11:31 +01:00
0592206f2d patch: doxy formatting 2020-12-03 22:44:08 +01:00
bedc2a443a fix: @cond on new line to prevent parsing issues in sasjs cli 2020-12-02 08:09:51 +01:00
6f86ed62a2 chore: doxy formatting 2020-11-29 22:03:20 +01:00
def0cc8476 fix: adding outds and parameters to mv_jobexecute 2020-11-29 21:55:21 +01:00
3a9029557e chore: doxygen updates 2020-11-29 21:06:39 +01:00
35 changed files with 645 additions and 235 deletions

459
all.sas
View File

@@ -39,7 +39,8 @@ options noquotelenmax;
@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=, msg=, iftrue=%str(1=1)
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
@@ -204,7 +205,8 @@ options noquotelenmax;
@version 8 @version 8
@author Allan Bowe @author Allan Bowe
**/ /** @cond */ **/
/** @cond */
%macro mf_existfeature(feature %macro mf_existfeature(feature
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
@@ -239,7 +241,8 @@ options noquotelenmax;
@param var (positional) - variable name @param var (positional) - variable name
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
**/ /** @cond */ **/
/** @cond */
%macro mf_existvar(libds /* 2 part dataset name */ %macro mf_existvar(libds /* 2 part dataset name */
, var /* variable name */ , var /* variable name */
@@ -275,6 +278,7 @@ options noquotelenmax;
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mf_existvarlist(libds, varlist %macro mf_existvarlist(libds, varlist
@@ -314,7 +318,9 @@ options noquotelenmax;
0 0
%put Vars not found: &found; %put Vars not found: &found;
%end; %end;
%mend;/** %mend;
/** @endcond *//**
@file @file
@brief Returns a character attribute of a dataset. @brief Returns a character attribute of a dataset.
@details Can be used in open code, eg as follows: @details Can be used in open code, eg as follows:
@@ -404,7 +410,8 @@ options noquotelenmax;
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
**/ /** @cond */ **/
/** @cond */
%macro mf_getengine(libref %macro mf_getengine(libref
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
@@ -629,6 +636,7 @@ options noquotelenmax;
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mf_getschema(libref %macro mf_getschema(libref
@@ -650,6 +658,8 @@ options noquotelenmax;
&schema &schema
%mend; %mend;
/** @endcond */
/** /**
@file @file
@brief Assigns and returns an unused fileref @brief Assigns and returns an unused fileref
@@ -1525,11 +1535,11 @@ Usage:
the particulars of an environment. For instance, can stream custom the particulars of an environment. For instance, can stream custom
results back to the client in an STP Web App context, or completely stop results back to the client in an STP Web App context, or completely stop
in the case of a batch run. in the case of a batch run.
Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored Process Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored Process
environments. This macro takes a unique approach - we set the SAS syscc to 0, environments. This macro takes a unique approach - we set the SAS syscc to 0,
run `stpsrvset('program error', 0)` (if SAS 9) and then - we open a macro run `stpsrvset('program error', 0)` (if SAS 9) and then - we open a macro
but don't close it! This provides a graceful abort for SAS web services in all but don't close it! This provides a graceful abort for SAS web services in all
web enabled environments. web enabled environments.
@param mac= to contain the name of the calling macro @param mac= to contain the name of the calling macro
@@ -1538,6 +1548,7 @@ Usage:
@version 9.4M3 @version 9.4M3
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1) %macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1)
@@ -1550,7 +1561,7 @@ Usage:
%put NOTE - &msg; %put NOTE - &msg;
/* Stored Process Server web app context */ /* Stored Process Server web app context */
%if %symexist(_metaperson) %if %symexist(_metaperson)
or (%symexist(SYSPROCESSNAME) and "&SYSPROCESSNAME"="Compute Server" ) or (%symexist(SYSPROCESSNAME) and "&SYSPROCESSNAME"="Compute Server" )
%then %do; %then %do;
options obs=max replace nosyntaxcheck mprint; options obs=max replace nosyntaxcheck mprint;
@@ -1671,7 +1682,7 @@ Usage:
%end; %end;
%mend; %mend;
/** /** @endcond *//**
@file @file
@brief Copy any file using binary input / output streams @brief Copy any file using binary input / output streams
@details Reads in a file byte by byte and writes it back out. Is an @details Reads in a file byte by byte and writes it back out. Is an
@@ -1735,6 +1746,7 @@ Usage:
applying CRLF line endings and converting embedded cr and crlf to lf. applying CRLF line endings and converting embedded cr and crlf to lf.
usage: usage:
fileref mycsv "/path/your/csv"; fileref mycsv "/path/your/csv";
%mp_cleancsv(in=mycsv,out=/path/new.csv) %mp_cleancsv(in=mycsv,out=/path/new.csv)
@@ -1744,6 +1756,7 @@ Usage:
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x); %macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x);
@@ -1792,7 +1805,8 @@ Usage:
else put inchar $char1.; else put inchar $char1.;
end; end;
run; run;
%mend;/** %mend;
/** @endcond *//**
@file mp_createconstraints.sas @file mp_createconstraints.sas
@brief Creates constraints @brief Creates constraints
@details Takes the output from mp_getconstraints.sas as input @details Takes the output from mp_getconstraints.sas as input
@@ -2631,6 +2645,63 @@ 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;/**
@file
@brief Export a dataset to a CSV file
@details Export to a file or a fileref
Usage:
%mp_ds2csv(sashelp.class,outref="%sysfunc(pathname(work))/file.csv")
@param ds The dataset to be exported
@param outfile= The output filename - should be quoted.
@param outref= The output fileref (takes precedence if provided)
@param outencoding= The output encoding to use (unquoted)
@version 9.2
@author Allan Bowe (credit mjsq)
**/
%macro mp_ds2csv(ds, outref=0, outfile=, outencoding=0
)/*/STORE SOURCE*/;
%if not %sysfunc(exist(&ds)) %then %do;
%put WARNING: &ds does not exist;
%return;
%end;
%if %index(&ds,.)=0 %then %let ds=WORK.&ds;
%if &outencoding=0 %then %let outencoding=;
%else %let outencoding=encoding="&outencoding";
%local outloc;
%if &outref=0 %then %let outloc=&outfile;
%else %let outloc=&outref;
/* credit to mjsq - https://stackoverflow.com/a/55642267 */
/* first get headers */
data _null_;
file &outloc dlm=',' dsd &outencoding lrecl=32767;
length header $ 2000;
dsid=open("&ds.","i");
num=attrn(dsid,"nvars");
do i=1 to num;
header = trim(left(coalescec(varlabel(dsid,i),varname(dsid,i))));
put header @;
end;
rc=close(dsid);
run;
/* next, export data */
data _null_;
set &ds.;
file &outloc mod dlm=',' dsd &outencoding lrecl=32767;
put (_all_) (+0);
run;
%mend;/** %mend;/**
@file mp_getconstraints.sas @file mp_getconstraints.sas
@brief Get constraint details at column level @brief Get constraint details at column level
@@ -2708,6 +2779,8 @@ create table &outds as
You may need to adjust the rendered DBML to suit your needs. You may need to adjust the rendered DBML to suit your needs.
![dbml for sas](https://i.imgur.com/8T1tIZp.gif)
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_getquotedstr.sas @li mf_getquotedstr.sas
@@ -3993,6 +4066,93 @@ select distinct lowcase(memname)
,dttm=%sysfunc(datetime()); ,dttm=%sysfunc(datetime());
quit; quit;
%mend;/**
@file
@brief Enables previous observations to be re-instated
@details Remembers the last X observations by storing them in a hash table.
Is a convenience over the use of lag() or retain, when an entire observation
needs to be restored.
This macro will also restore automatic variables (such as _n_ and _error_).
Example Usage:
data example;
set sashelp.class;
calc_var=_n_*3;
* initialise hash and save from PDV ;
%mp_prevobs(INIT,history=2)
if _n_ =10 then do;
* fetch previous but 1 record;
%mp_prevobs(FETCH,-2)
put _n_= name= age= calc_var=;
* fetch previous record;
%mp_prevobs(FETCH,-1)
put _n_= name= age= calc_var=;
* reinstate current record ;
%mp_prevobs(FETCH,0)
put _n_= name= age= calc_var=;
end;
run;
Result:
<img src="https://imgur.com/PSjHoET.png" alt="mp_prevobs sas" width="400"/>
Credit is made to `data _null_` for authoring this very helpful paper:
https://www.lexjansen.com/pharmasug/2008/cc/CC08.pdf
@param action Either FETCH a current or previous record, or INITialise.
@param record The relative (to current) position of the previous observation
to return.
@param history= The number of records to retain in the hash table. Default=5
@param prefix= the prefix to give to the variables used to store the hash name
and index. Default=mp_prevobs
@version 9.2
@author Allan Bowe
**/
%macro mp_prevobs(action,record,history=5,prefix=mp_prevobs
)/*/STORE SOURCE*/;
%let action=%upcase(&action);
%let prefix=%upcase(&prefix);
%let record=%eval((&record+0) * -1);
%if &action=INIT %then %do;
if _n_ eq 1 then do;
attrib &prefix._VAR length=$64;
dcl hash &prefix._HASH(ordered:'Y');
&prefix._KEY=0;
&prefix._HASH.defineKey("&prefix._KEY");
do while(1);
call vnext(&prefix._VAR);
if &prefix._VAR='' then leave;
if &prefix._VAR eq "&prefix._VAR" then continue;
else if &prefix._VAR eq "&prefix._KEY" then continue;
&prefix._HASH.defineData(&prefix._VAR);
end;
&prefix._HASH.defineDone();
end;
/* this part has to happen before FETCHing */
&prefix._KEY+1;
&prefix._rc=&prefix._HASH.add();
if &prefix._rc then putlog 'adding' &prefix._rc=;
%if &history>0 %then %do;
if &prefix._key>&history+1 then
&prefix._HASH.remove(key: &prefix._KEY - &history - 1);
if &prefix._rc then putlog 'removing' &prefix._rc=;
%end;
%end;
%else %if &action=FETCH %then %do;
if &record > &prefix._key then putlog "Not enough records in &Prefix._hash yet";
else &prefix._rc=&prefix._HASH.find(key: &prefix._KEY - &record);
if &prefix._rc then putlog &prefix._rc= " when fetching " &prefix._KEY=
"with record &record and " _n_=;
%end;
%mend;/** %mend;/**
@file @file
@brief Returns all children from a hierarchy table for a specified parent @brief Returns all children from a hierarchy table for a specified parent
@@ -4594,6 +4754,64 @@ proc sql
%mp_binarycopy(inloc="&inloc",outref=_webout) %mp_binarycopy(inloc="&inloc",outref=_webout)
%end; %end;
%mend;/**
@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> Dependencies </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;/** %mend;/**
@file @file
@brief Recursively scans a directory tree to get all subfolders and content @brief Recursively scans a directory tree to get all subfolders and content
@@ -10329,8 +10547,7 @@ run;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -10356,7 +10573,7 @@ run;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -10435,7 +10652,7 @@ options noquotelenmax;
out=&fname2 out=&fname2
&oauth_bearer &oauth_bearer
url=%unquote(%superq(href)); url=%unquote(%superq(href));
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
@@ -10467,27 +10684,28 @@ options noquotelenmax;
%mend;/** %mend;/**
@file mv_createwebservice.sas @file mv_createwebservice.sas
@brief Creates a JobExecution web service if it doesn't already exist @brief Creates a JobExecution web service if it doesn't already exist
@details Code is passed in as one or more filerefs. @details
Code is passed in as one or more filerefs.
%* Step 1 - compile macros ; %* Step 1 - compile macros ;
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
%inc mc; %inc mc;
%* Step 2 - Create some code and add it to a web service; %* Step 2 - Create some code and add it to a web service;
filename ft15f001 temp; filename ft15f001 temp;
parmcards4; parmcards4;
%webout(FETCH) %* fetch any tables sent from frontend; %webout(FETCH) %* fetch any tables sent from frontend;
%* do some sas, any inputs are now already WORK tables; %* do some sas, any inputs are now already WORK tables;
data example1 example2; data example1 example2;
set sashelp.class; set sashelp.class;
run; run;
%* send data back; %* send data back;
%webout(OPEN) %webout(OPEN)
%webout(ARR,example1) * Array format, fast, suitable for large tables ; %webout(ARR,example1) * Array format, fast, suitable for large tables ;
%webout(OBJ,example2) * Object format, easier to work with ; %webout(OBJ,example2) * Object format, easier to work with ;
%webout(CLOSE) %webout(CLOSE)
;;;; ;;;;
%mv_createwebservice(path=/Public/app/common,name=appinit) %mv_createwebservice(path=/Public/app/common,name=appinit)
Notes: Notes:
@@ -10520,8 +10738,7 @@ options noquotelenmax;
a shared context - see https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en a shared context - see https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
**/ **/
@@ -11124,7 +11341,7 @@ run;
/** /**
@file mv_deletefoldermember.sas @file mv_deletefoldermember.sas
@brief Deletes an item in a Viya folder @brief Deletes an item in a Viya folder
@details If not executed in Studio 5+ will expect oauth token in a global @details If not executed in Studio 5+ will expect oauth token in a global
macro variable (default ACCESS_TOKEN). macro variable (default ACCESS_TOKEN).
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
@@ -11143,8 +11360,7 @@ run;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11171,7 +11387,7 @@ run;
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -11252,7 +11468,7 @@ run;
%return; %return;
%end; %end;
proc http method="DELETE" url="&base_uri&uri" &oauth_bearer; proc http method="DELETE" url="&base_uri&uri" &oauth_bearer;
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
@@ -11275,7 +11491,7 @@ libname &libref1a clear;
%mend;/** %mend;/**
@file mv_deletejes.sas @file mv_deletejes.sas
@brief Creates a job execution service if it does not already exist @brief Creates a job execution service if it does not already exist
@details If not executed in Studio 5+ will expect oauth token in a global @details If not executed in Studio 5+ will expect oauth token in a global
macro variable (default ACCESS_TOKEN). macro variable (default ACCESS_TOKEN).
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
@@ -11293,8 +11509,7 @@ libname &libref1a clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11320,7 +11535,7 @@ libname &libref1a clear;
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -11400,7 +11615,7 @@ run;
%return; %return;
%end; %end;
proc http method="DELETE" url="&uri" &oauth_bearer; proc http method="DELETE" url="&uri" &oauth_bearer;
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
@@ -11423,7 +11638,7 @@ libname &libref1a clear;
%mend;/** %mend;/**
@file mv_deleteviyafolder.sas @file mv_deleteviyafolder.sas
@brief Creates a viya folder if that folder does not already exist @brief Creates a viya folder if that folder does not already exist
@details If not running in Studo 5 +, will expect an oauth token in a global @details If not running in Studo 5 +, will expect an oauth token in a global
macro variable (default ACCESS_TOKEN). macro variable (default ACCESS_TOKEN).
options mprint; options mprint;
@@ -11438,8 +11653,7 @@ libname &libref1a clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11464,7 +11678,7 @@ libname &libref1a clear;
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -11543,10 +11757,10 @@ run;
%let fname2=%mf_getuniquefileref(); %let fname2=%mf_getuniquefileref();
proc http method='DELETE' out=&fname2 &oauth_bearer proc http method='DELETE' out=&fname2 &oauth_bearer
url=%unquote(%superq(href)); url=%unquote(%superq(href));
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
'Accept'='*/*'; /**/ 'Accept'='*/*'; /**/
run; run;
%if &SYS_PROCHTTP_STATUS_CODE ne 204 %then %do; %if &SYS_PROCHTTP_STATUS_CODE ne 204 %then %do;
@@ -11567,14 +11781,13 @@ libname &libref1 clear;
@brief deprecated - replaced by mv_tokenrefresh.sas @brief deprecated - replaced by mv_tokenrefresh.sas
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mv_tokenrefresh.sas @li mv_tokenrefresh.sas
**/ **/
%macro mv_getaccesstoken(client_id=someclient %macro mv_getaccesstoken(client_id=someclient
,client_secret=somesecret ,client_secret=somesecret
,grant_type=authorization_code ,grant_type=authorization_code
@@ -11599,14 +11812,13 @@ libname &libref1 clear;
@brief deprecated - replaced by mv_registerclient.sas @brief deprecated - replaced by mv_registerclient.sas
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mv_registerclient.sas @li mv_registerclient.sas
**/ **/
%macro mv_getapptoken(client_id=someclient %macro mv_getapptoken(client_id=someclient
,client_secret=somesecret ,client_secret=somesecret
,grant_type=authorization_code ,grant_type=authorization_code
@@ -11648,8 +11860,7 @@ libname &libref1 clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11714,7 +11925,7 @@ run;
/* clear refs /* clear refs
filename &fname1 clear; filename &fname1 clear;
libname &libref1 clear; libname &libref1 clear;
*/ */
@@ -11735,8 +11946,7 @@ libname &libref1 clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11869,8 +12079,7 @@ libname &libref1 clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11895,7 +12104,7 @@ libname &libref1 clear;
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -11912,7 +12121,7 @@ options noquotelenmax;
%let fname1=%mf_getuniquefileref(); %let fname1=%mf_getuniquefileref();
proc http method='GET' out=&fname1 &oauth_bearer proc http method='GET' out=&fname1 &oauth_bearer
url="&base_uri/identities/groups/&group/members?limit=10000"; url="&base_uri/identities/groups/&group/members?limit=10000";
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
@@ -11974,8 +12183,7 @@ filename &fname1 clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -11999,7 +12207,7 @@ filename &fname1 clear;
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -12017,7 +12225,7 @@ options noquotelenmax;
proc http method='GET' out=&fname1 &oauth_bearer proc http method='GET' out=&fname1 &oauth_bearer
url="&base_uri/identities/groups?limit=10000"; url="&base_uri/identities/groups?limit=10000";
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
@@ -12045,14 +12253,13 @@ libname &libref1 clear;
@brief deprecated - replaced by mv_tokenauth.sas @brief deprecated - replaced by mv_tokenauth.sas
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mv_tokenauth.sas @li mv_tokenauth.sas
**/ **/
%macro mv_getrefreshtoken(client_id=someclient %macro mv_getrefreshtoken(client_id=someclient
,client_secret=somesecret ,client_secret=somesecret
,grant_type=authorization_code ,grant_type=authorization_code
@@ -12095,8 +12302,7 @@ libname &libref1 clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -12201,12 +12407,12 @@ libname &libref1 clear;
creationTimeStamp char(24), creationTimeStamp char(24),
modifiedTimeStamp char(24), modifiedTimeStamp char(24),
state char(6) state char(6)
@param access_token_var= The global macro variable to contain the access token @param access_token_var= The global macro variable to contain the access token
@param grant_type= valid values: @param grant_type= valid values:
* password * password
* authorization_code * authorization_code
* detect - will check if access_token exists, if not will use sas_services if * detect - will check if access_token exists, if not will use sas_services if
a SASStudioV session else authorization_code. Default option. a SASStudioV session else authorization_code. Default option.
* sas_services - will use oauth_bearer=sas_services * sas_services - will use oauth_bearer=sas_services
@@ -12214,8 +12420,7 @@ libname &libref1 clear;
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -12239,7 +12444,7 @@ libname &libref1 clear;
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -12299,6 +12504,12 @@ libname &libref1 clear;
,name=somejob ,name=somejob
) )
Example with parameters:
%mv_jobexecute(path=/Public/folder
,name=somejob
,paramstring=%str("macvarname":"macvarvalue","answer":42)
)
@param access_token_var= The global macro variable to contain the access token @param access_token_var= The global macro variable to contain the access token
@param grant_type= valid values: @param grant_type= valid values:
@@ -12310,10 +12521,14 @@ libname &libref1 clear;
@param path= The SAS Drive path to the job being executed @param path= The SAS Drive path to the job being executed
@param name= The name of the job to execute @param name= The name of the job to execute
@param params= A macro quoted string to append to the URL @param paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"`
or "name":"value","name2":42`. This will need to be wrapped in `%str()`.
@param contextName= Context name with which to run the job. @param contextName= Context name with which to run the job.
Default = `SAS Job Execution compute context` Default = `SAS Job Execution compute context`
@param outds= The output dataset containing links (Default=work.mv_jobexecute)
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -12322,6 +12537,7 @@ libname &libref1 clear;
@li mp_abort.sas @li mp_abort.sas
@li mf_getplatform.sas @li mf_getplatform.sas
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mv_getfoldermembers.sas @li mv_getfoldermembers.sas
**/ **/
@@ -12331,6 +12547,8 @@ libname &libref1 clear;
,contextName=SAS Job Execution compute context ,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN ,access_token_var=ACCESS_TOKEN
,grant_type=sas_services ,grant_type=sas_services
,paramstring=0
,outds=work.mv_jobexecute
); );
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
@@ -12392,11 +12610,16 @@ run;
data _null_; data _null_;
file &fname0; file &fname0;
put '{"jobDefinitionUri": "'@@; length joburi contextname $128 paramstring $32765;
put "&joburi"@@; joburi=quote(trim(symget('joburi')));
put '","arguments":{"_contextName":"'@@; contextname=quote(trim(symget('contextname')));
put "&contextName"@@; paramstring=symget('paramstring');
put '"}}'; put '{"jobDefinitionUri":' joburi ;
put ' ,"arguments":{"_contextName":' contextname;
if paramstring ne "0" then do;
put ' ,' paramstring;
end;
put '}}';
run; run;
proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
@@ -12408,18 +12631,27 @@ proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
%end; %end;
; ;
run; run;
/*data _null_;infile &fname1;input;putlog _infile_;run;*/ %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
%do;
%mp_abort(iftrue=( data _null_;infile &fname0;input;putlog _infile_;run;
&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 data _null_;infile &fname1;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) )
,mac=&sysmacroname %end;
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) %local libref;
%let libref=%mf_getuniquelibref();
libname &libref JSON fileref=&fname1;
data &outds;
set &libref..links;
run;
/* clear refs */ /* clear refs */
filename &fname0 clear; filename &fname0 clear;
filename &fname1 clear; filename &fname1 clear;
libname &libref;
%mend;/** %mend;/**
@file mv_registerclient.sas @file mv_registerclient.sas
@@ -12458,25 +12690,24 @@ filename &fname1 clear;
@param scopes= list of space-seperated unquoted scopes (default is openid) @param scopes= list of space-seperated unquoted scopes (default is openid)
@param grant_type= valid values are "password" or "authorization_code" (unquoted) @param grant_type= valid values are "password" or "authorization_code" (unquoted)
@param outds= the dataset to contain the registered client id and secret @param outds= the dataset to contain the registered client id and secret
@param access_token_validity= The duration of validity of the access token @param access_token_validity= The duration of validity of the access token
in seconds. A value of DEFAULT will omit the entry (and use system default) in seconds. A value of DEFAULT will omit the entry (and use system default)
@param refresh_token_validity= The duration of validity of the refresh token @param refresh_token_validity= The duration of validity of the refresh token
in seconds. A value of DEFAULT will omit the entry (and use system default) in seconds. A value of DEFAULT will omit the entry (and use system default)
@param name= A human readable name for the client @param name= A human readable name for the client
@param required_user_groups= A list of group names. If a user does not belong @param required_user_groups= A list of group names. If a user does not belong
to all the required groups, the user will not be authenticated and no tokens to all the required groups, the user will not be authenticated and no tokens
are issued to this client for that user. If this field is not specified, are issued to this client for that user. If this field is not specified,
authentication and token issuance proceeds normally. authentication and token issuance proceeds normally.
@param autoapprove= During the auth step the user can choose which scope to @param autoapprove= During the auth step the user can choose which scope to
apply. Setting this to true will autoapprove all the client scopes. apply. Setting this to true will autoapprove all the client scopes.
@param use_session= If true, access tokens issued to this client will be @param use_session= If true, access tokens issued to this client will be
associated with an HTTP session and revoked upon logout or time-out. associated with an HTTP session and revoked upon logout or time-out.
@param outjson= A dataset containing the lines of JSON submitted. Useful @param outjson= A dataset containing the lines of JSON submitted. Useful
for debugging. Default= _null_. for debugging. Default= _null_.
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -12566,7 +12797,7 @@ data _null_;
if not missing(autoapprove) then autoapprove=cats(',"autoapprove":',autoapprove); if not missing(autoapprove) then autoapprove=cats(',"autoapprove":',autoapprove);
use_session=trim(symget('use_session')); use_session=trim(symget('use_session'));
if not missing(use_session) then use_session=cats(',"use_session":',use_session); if not missing(use_session) then use_session=cats(',"use_session":',use_session);
put '{' clientid ; put '{' clientid ;
put clientsecret ; put clientsecret ;
put clientname; put clientname;
@@ -12699,8 +12930,7 @@ libname &libref clear;
@param base_uri= The Viya API server location @param base_uri= The Viya API server location
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -12842,8 +13072,7 @@ filename &fref2 clear;
@param refresh_token_var= The global macro variable containing the refresh token @param refresh_token_var= The global macro variable containing the refresh token
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -12965,13 +13194,13 @@ filename &fref1 clear;
@li mf_getuser.sas @li mf_getuser.sas
@version Viya 3.3 @version Viya 3.3
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
**/ **/
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y); %macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y);
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name %global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
sasjs_tables SYS_JES_JOB_URI; sasjs_tables SYS_JES_JOB_URI;
%if %index("&_debug",log) %then %let _debug=131; %if %index("&_debug",log) %then %let _debug=131;
%local i tempds; %local i tempds;
%let action=%upcase(&action); %let action=%upcase(&action);
@@ -13077,8 +13306,8 @@ filename &fref1 clear;
filename _webout temp lrecl=999999 mod; filename _webout temp lrecl=999999 mod;
%end; %end;
%else %do; %else %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
name="_webout.json" lrecl=999999 mod; name="_webout.json" lrecl=999999 mod;
%end; %end;
/* setup temp ref */ /* setup temp ref */

View File

@@ -21,7 +21,8 @@
@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=, msg=, iftrue=%str(1=1)
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;

View File

@@ -19,7 +19,8 @@
@version 8 @version 8
@author Allan Bowe @author Allan Bowe
**/ /** @cond */ **/
/** @cond */
%macro mf_existfeature(feature %macro mf_existfeature(feature
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;

View File

@@ -11,7 +11,8 @@
@param var (positional) - variable name @param var (positional) - variable name
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
**/ /** @cond */ **/
/** @cond */
%macro mf_existvar(libds /* 2 part dataset name */ %macro mf_existvar(libds /* 2 part dataset name */
, var /* variable name */ , var /* variable name */

View File

@@ -14,6 +14,7 @@
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mf_existvarlist(libds, varlist %macro mf_existvarlist(libds, varlist
@@ -53,4 +54,6 @@
0 0
%put Vars not found: &found; %put Vars not found: &found;
%end; %end;
%mend; %mend;
/** @endcond */

View File

@@ -22,7 +22,8 @@
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
**/ /** @cond */ **/
/** @cond */
%macro mf_getengine(libref %macro mf_getengine(libref
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;

View File

@@ -17,6 +17,7 @@
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mf_getschema(libref %macro mf_getschema(libref
@@ -38,3 +39,5 @@
&schema &schema
%mend; %mend;
/** @endcond */

View File

@@ -5,11 +5,11 @@
the particulars of an environment. For instance, can stream custom the particulars of an environment. For instance, can stream custom
results back to the client in an STP Web App context, or completely stop results back to the client in an STP Web App context, or completely stop
in the case of a batch run. in the case of a batch run.
Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored Process Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored Process
environments. This macro takes a unique approach - we set the SAS syscc to 0, environments. This macro takes a unique approach - we set the SAS syscc to 0,
run `stpsrvset('program error', 0)` (if SAS 9) and then - we open a macro run `stpsrvset('program error', 0)` (if SAS 9) and then - we open a macro
but don't close it! This provides a graceful abort for SAS web services in all but don't close it! This provides a graceful abort for SAS web services in all
web enabled environments. web enabled environments.
@param mac= to contain the name of the calling macro @param mac= to contain the name of the calling macro
@@ -18,6 +18,7 @@
@version 9.4M3 @version 9.4M3
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1) %macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1)
@@ -30,7 +31,7 @@
%put NOTE - &msg; %put NOTE - &msg;
/* Stored Process Server web app context */ /* Stored Process Server web app context */
%if %symexist(_metaperson) %if %symexist(_metaperson)
or (%symexist(SYSPROCESSNAME) and "&SYSPROCESSNAME"="Compute Server" ) or (%symexist(SYSPROCESSNAME) and "&SYSPROCESSNAME"="Compute Server" )
%then %do; %then %do;
options obs=max replace nosyntaxcheck mprint; options obs=max replace nosyntaxcheck mprint;
@@ -151,3 +152,4 @@
%end; %end;
%mend; %mend;
/** @endcond */

View File

@@ -8,6 +8,7 @@
applying CRLF line endings and converting embedded cr and crlf to lf. applying CRLF line endings and converting embedded cr and crlf to lf.
usage: usage:
fileref mycsv "/path/your/csv"; fileref mycsv "/path/your/csv";
%mp_cleancsv(in=mycsv,out=/path/new.csv) %mp_cleancsv(in=mycsv,out=/path/new.csv)
@@ -17,6 +18,7 @@
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
@cond
**/ **/
%macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x); %macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x);
@@ -65,4 +67,5 @@
else put inchar $char1.; else put inchar $char1.;
end; end;
run; run;
%mend; %mend;
/** @endcond */

58
base/mp_ds2csv.sas Normal file
View File

@@ -0,0 +1,58 @@
/**
@file
@brief Export a dataset to a CSV file
@details Export to a file or a fileref
Usage:
%mp_ds2csv(sashelp.class,outref="%sysfunc(pathname(work))/file.csv")
@param ds The dataset to be exported
@param outfile= The output filename - should be quoted.
@param outref= The output fileref (takes precedence if provided)
@param outencoding= The output encoding to use (unquoted)
@version 9.2
@author Allan Bowe (credit mjsq)
**/
%macro mp_ds2csv(ds, outref=0, outfile=, outencoding=0
)/*/STORE SOURCE*/;
%if not %sysfunc(exist(&ds)) %then %do;
%put WARNING: &ds does not exist;
%return;
%end;
%if %index(&ds,.)=0 %then %let ds=WORK.&ds;
%if &outencoding=0 %then %let outencoding=;
%else %let outencoding=encoding="&outencoding";
%local outloc;
%if &outref=0 %then %let outloc=&outfile;
%else %let outloc=&outref;
/* credit to mjsq - https://stackoverflow.com/a/55642267 */
/* first get headers */
data _null_;
file &outloc dlm=',' dsd &outencoding lrecl=32767;
length header $ 2000;
dsid=open("&ds.","i");
num=attrn(dsid,"nvars");
do i=1 to num;
header = trim(left(coalescec(varlabel(dsid,i),varname(dsid,i))));
put header @;
end;
rc=close(dsid);
run;
/* next, export data */
data _null_;
set &ds.;
file &outloc mod dlm=',' dsd &outencoding lrecl=32767;
put (_all_) (+0);
run;
%mend;

View File

@@ -16,6 +16,8 @@
You may need to adjust the rendered DBML to suit your needs. You may need to adjust the rendered DBML to suit your needs.
![dbml for sas](https://i.imgur.com/8T1tIZp.gif)
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_getquotedstr.sas @li mf_getquotedstr.sas

88
base/mp_prevobs.sas Normal file
View File

@@ -0,0 +1,88 @@
/**
@file
@brief Enables previous observations to be re-instated
@details Remembers the last X observations by storing them in a hash table.
Is a convenience over the use of lag() or retain, when an entire observation
needs to be restored.
This macro will also restore automatic variables (such as _n_ and _error_).
Example Usage:
data example;
set sashelp.class;
calc_var=_n_*3;
* initialise hash and save from PDV ;
%mp_prevobs(INIT,history=2)
if _n_ =10 then do;
* fetch previous but 1 record;
%mp_prevobs(FETCH,-2)
put _n_= name= age= calc_var=;
* fetch previous record;
%mp_prevobs(FETCH,-1)
put _n_= name= age= calc_var=;
* reinstate current record ;
%mp_prevobs(FETCH,0)
put _n_= name= age= calc_var=;
end;
run;
Result:
<img src="https://imgur.com/PSjHoET.png" alt="mp_prevobs sas" width="400"/>
Credit is made to `data _null_` for authoring this very helpful paper:
https://www.lexjansen.com/pharmasug/2008/cc/CC08.pdf
@param action Either FETCH a current or previous record, or INITialise.
@param record The relative (to current) position of the previous observation
to return.
@param history= The number of records to retain in the hash table. Default=5
@param prefix= the prefix to give to the variables used to store the hash name
and index. Default=mp_prevobs
@version 9.2
@author Allan Bowe
**/
%macro mp_prevobs(action,record,history=5,prefix=mp_prevobs
)/*/STORE SOURCE*/;
%let action=%upcase(&action);
%let prefix=%upcase(&prefix);
%let record=%eval((&record+0) * -1);
%if &action=INIT %then %do;
if _n_ eq 1 then do;
attrib &prefix._VAR length=$64;
dcl hash &prefix._HASH(ordered:'Y');
&prefix._KEY=0;
&prefix._HASH.defineKey("&prefix._KEY");
do while(1);
call vnext(&prefix._VAR);
if &prefix._VAR='' then leave;
if &prefix._VAR eq "&prefix._VAR" then continue;
else if &prefix._VAR eq "&prefix._KEY" then continue;
&prefix._HASH.defineData(&prefix._VAR);
end;
&prefix._HASH.defineDone();
end;
/* this part has to happen before FETCHing */
&prefix._KEY+1;
&prefix._rc=&prefix._HASH.add();
if &prefix._rc then putlog 'adding' &prefix._rc=;
%if &history>0 %then %do;
if &prefix._key>&history+1 then
&prefix._HASH.remove(key: &prefix._KEY - &history - 1);
if &prefix._rc then putlog 'removing' &prefix._rc=;
%end;
%end;
%else %if &action=FETCH %then %do;
if &record > &prefix._key then putlog "Not enough records in &Prefix._hash yet";
else &prefix._rc=&prefix._HASH.find(key: &prefix._KEY - &record);
if &prefix._rc then putlog &prefix._rc= " when fetching " &prefix._KEY=
"with record &record and " _n_=;
%end;
%mend;

View File

@@ -24,7 +24,7 @@ LAYOUT_FILE = ./doxy/DoxygenLayout.xml
MAX_INITIALIZER_LINES = 0 MAX_INITIALIZER_LINES = 0
PROJECT_NAME = Macro Core PROJECT_NAME = Macro Core
PROJECT_LOGO = doxy/Macro_core_website_1.png PROJECT_LOGO = doxy/Macro_core_website_1.png
PROJECT_BRIEF = placeholder PROJECT_BRIEF = "Production Ready Macros for SAS Application Developers"
RECURSIVE = YES RECURSIVE = YES
REPEAT_BRIEF = NO REPEAT_BRIEF = NO
SHOW_NAMESPACES = NO SHOW_NAMESPACES = NO

View File

@@ -33,11 +33,11 @@ cd core.github.io
rm -r * rm -r *
mv $BUILD_FOLDER/out/doxy/* . mv $BUILD_FOLDER/out/doxy/* .
echo 'core.sasjs.io' > CNAME echo 'core.sasjs.io' > CNAME
git add * git add .
git commit -m "build.sh build on $(date +%F:%H:%M:%S)" git commit -m "build.sh build on $(date +%F:%H:%M:%S)"
git push git push
npx sitemap-generator-cli https://core.sasjs.io npx sitemap-generator-cli https://core.sasjs.io
git add * git add .
git commit -m "adding sitemap" git commit -m "adding sitemap"
git push git push

View File

@@ -1,6 +1,6 @@
<!-- HTML header for doxygen 1.8.17-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <!-- HTML header for doxygen 1.8.17-->
<html xmlns="https://www.w3.org/1999/xhtml" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/> <meta http-equiv="X-UA-Compatible" content="IE=9"/>
@@ -41,7 +41,9 @@ $extrastylesheet
https://github.com/sasjs/core https://github.com/sasjs/core
</a> </a>
</div><!--END PROJECT_BRIEF--> </div>
<meta name="Description" content="$projectbrief">
<!--END PROJECT_BRIEF-->
</td> </td>
<!--END PROJECT_NAME--> <!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--> <!--BEGIN !PROJECT_NAME-->

View File

@@ -13,6 +13,11 @@
* Not metadata aware * Not metadata aware
* No X command * No X command
* Prefixes: _mf_, _mp_ * Prefixes: _mf_, _mp_
Macros starting `mf_` are macro _functions_ and can be used in assignment
statements. Those starting `mp_` are macro _procedures_, which generate
SAS statements, and must therefore be applied accordingly.
*/ */
/*! \dir meta /*! \dir meta

View File

@@ -15,8 +15,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -42,7 +41,7 @@
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -121,7 +120,7 @@ options noquotelenmax;
out=&fname2 out=&fname2
&oauth_bearer &oauth_bearer
url=%unquote(%superq(href)); url=%unquote(%superq(href));
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;

View File

@@ -1,27 +1,28 @@
/** /**
@file mv_createwebservice.sas @file mv_createwebservice.sas
@brief Creates a JobExecution web service if it doesn't already exist @brief Creates a JobExecution web service if it doesn't already exist
@details Code is passed in as one or more filerefs. @details
Code is passed in as one or more filerefs.
%* Step 1 - compile macros ; %* Step 1 - compile macros ;
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
%inc mc; %inc mc;
%* Step 2 - Create some code and add it to a web service; %* Step 2 - Create some code and add it to a web service;
filename ft15f001 temp; filename ft15f001 temp;
parmcards4; parmcards4;
%webout(FETCH) %* fetch any tables sent from frontend; %webout(FETCH) %* fetch any tables sent from frontend;
%* do some sas, any inputs are now already WORK tables; %* do some sas, any inputs are now already WORK tables;
data example1 example2; data example1 example2;
set sashelp.class; set sashelp.class;
run; run;
%* send data back; %* send data back;
%webout(OPEN) %webout(OPEN)
%webout(ARR,example1) * Array format, fast, suitable for large tables ; %webout(ARR,example1) * Array format, fast, suitable for large tables ;
%webout(OBJ,example2) * Object format, easier to work with ; %webout(OBJ,example2) * Object format, easier to work with ;
%webout(CLOSE) %webout(CLOSE)
;;;; ;;;;
%mv_createwebservice(path=/Public/app/common,name=appinit) %mv_createwebservice(path=/Public/app/common,name=appinit)
Notes: Notes:
@@ -54,8 +55,7 @@
a shared context - see https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en a shared context - see https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
**/ **/

View File

@@ -1,7 +1,7 @@
/** /**
@file mv_deletefoldermember.sas @file mv_deletefoldermember.sas
@brief Deletes an item in a Viya folder @brief Deletes an item in a Viya folder
@details If not executed in Studio 5+ will expect oauth token in a global @details If not executed in Studio 5+ will expect oauth token in a global
macro variable (default ACCESS_TOKEN). macro variable (default ACCESS_TOKEN).
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
@@ -20,8 +20,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -48,7 +47,7 @@
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -129,7 +128,7 @@ run;
%return; %return;
%end; %end;
proc http method="DELETE" url="&base_uri&uri" &oauth_bearer; proc http method="DELETE" url="&base_uri&uri" &oauth_bearer;
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;

View File

@@ -1,7 +1,7 @@
/** /**
@file mv_deletejes.sas @file mv_deletejes.sas
@brief Creates a job execution service if it does not already exist @brief Creates a job execution service if it does not already exist
@details If not executed in Studio 5+ will expect oauth token in a global @details If not executed in Studio 5+ will expect oauth token in a global
macro variable (default ACCESS_TOKEN). macro variable (default ACCESS_TOKEN).
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
@@ -19,8 +19,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -46,7 +45,7 @@
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -126,7 +125,7 @@ run;
%return; %return;
%end; %end;
proc http method="DELETE" url="&uri" &oauth_bearer; proc http method="DELETE" url="&uri" &oauth_bearer;
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;

View File

@@ -1,7 +1,7 @@
/** /**
@file mv_deleteviyafolder.sas @file mv_deleteviyafolder.sas
@brief Creates a viya folder if that folder does not already exist @brief Creates a viya folder if that folder does not already exist
@details If not running in Studo 5 +, will expect an oauth token in a global @details If not running in Studo 5 +, will expect an oauth token in a global
macro variable (default ACCESS_TOKEN). macro variable (default ACCESS_TOKEN).
options mprint; options mprint;
@@ -16,8 +16,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -42,7 +41,7 @@
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -121,10 +120,10 @@ run;
%let fname2=%mf_getuniquefileref(); %let fname2=%mf_getuniquefileref();
proc http method='DELETE' out=&fname2 &oauth_bearer proc http method='DELETE' out=&fname2 &oauth_bearer
url=%unquote(%superq(href)); url=%unquote(%superq(href));
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;
'Accept'='*/*'; /**/ 'Accept'='*/*'; /**/
run; run;
%if &SYS_PROCHTTP_STATUS_CODE ne 204 %then %do; %if &SYS_PROCHTTP_STATUS_CODE ne 204 %then %do;

View File

@@ -3,14 +3,13 @@
@brief deprecated - replaced by mv_tokenrefresh.sas @brief deprecated - replaced by mv_tokenrefresh.sas
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mv_tokenrefresh.sas @li mv_tokenrefresh.sas
**/ **/
%macro mv_getaccesstoken(client_id=someclient %macro mv_getaccesstoken(client_id=someclient
,client_secret=somesecret ,client_secret=somesecret
,grant_type=authorization_code ,grant_type=authorization_code

View File

@@ -3,14 +3,13 @@
@brief deprecated - replaced by mv_registerclient.sas @brief deprecated - replaced by mv_registerclient.sas
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mv_registerclient.sas @li mv_registerclient.sas
**/ **/
%macro mv_getapptoken(client_id=someclient %macro mv_getapptoken(client_id=someclient
,client_secret=somesecret ,client_secret=somesecret
,grant_type=authorization_code ,grant_type=authorization_code

View File

@@ -29,8 +29,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -95,7 +94,7 @@ run;
/* clear refs /* clear refs
filename &fname1 clear; filename &fname1 clear;
libname &libref1 clear; libname &libref1 clear;
*/ */

View File

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

View File

@@ -30,8 +30,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -56,7 +55,7 @@
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -73,7 +72,7 @@ options noquotelenmax;
%let fname1=%mf_getuniquefileref(); %let fname1=%mf_getuniquefileref();
proc http method='GET' out=&fname1 &oauth_bearer proc http method='GET' out=&fname1 &oauth_bearer
url="&base_uri/identities/groups/&group/members?limit=10000"; url="&base_uri/identities/groups/&group/members?limit=10000";
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;

View File

@@ -29,8 +29,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -54,7 +53,7 @@
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname
@@ -72,7 +71,7 @@ options noquotelenmax;
proc http method='GET' out=&fname1 &oauth_bearer proc http method='GET' out=&fname1 &oauth_bearer
url="&base_uri/identities/groups?limit=10000"; url="&base_uri/identities/groups?limit=10000";
headers headers
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; %end;

View File

@@ -3,14 +3,13 @@
@brief deprecated - replaced by mv_tokenauth.sas @brief deprecated - replaced by mv_tokenauth.sas
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mv_tokenauth.sas @li mv_tokenauth.sas
**/ **/
%macro mv_getrefreshtoken(client_id=someclient %macro mv_getrefreshtoken(client_id=someclient
,client_secret=somesecret ,client_secret=somesecret
,grant_type=authorization_code ,grant_type=authorization_code

View File

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

View File

@@ -34,12 +34,12 @@
creationTimeStamp char(24), creationTimeStamp char(24),
modifiedTimeStamp char(24), modifiedTimeStamp char(24),
state char(6) state char(6)
@param access_token_var= The global macro variable to contain the access token @param access_token_var= The global macro variable to contain the access token
@param grant_type= valid values: @param grant_type= valid values:
* password * password
* authorization_code * authorization_code
* detect - will check if access_token exists, if not will use sas_services if * detect - will check if access_token exists, if not will use sas_services if
a SASStudioV session else authorization_code. Default option. a SASStudioV session else authorization_code. Default option.
* sas_services - will use oauth_bearer=sas_services * sas_services - will use oauth_bearer=sas_services
@@ -47,8 +47,7 @@
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -72,7 +71,7 @@
%let &access_token_var=; %let &access_token_var=;
%end; %end;
%put &sysmacroname: grant_type=&grant_type; %put &sysmacroname: grant_type=&grant_type;
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password %mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
and &grant_type ne sas_services and &grant_type ne sas_services
) )
,mac=&sysmacroname ,mac=&sysmacroname

View File

@@ -16,6 +16,12 @@
,name=somejob ,name=somejob
) )
Example with parameters:
%mv_jobexecute(path=/Public/folder
,name=somejob
,paramstring=%str("macvarname":"macvarvalue","answer":42)
)
@param access_token_var= The global macro variable to contain the access token @param access_token_var= The global macro variable to contain the access token
@param grant_type= valid values: @param grant_type= valid values:
@@ -27,10 +33,14 @@
@param path= The SAS Drive path to the job being executed @param path= The SAS Drive path to the job being executed
@param name= The name of the job to execute @param name= The name of the job to execute
@param params= A macro quoted string to append to the URL @param paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"`
or "name":"value","name2":42`. This will need to be wrapped in `%str()`.
@param contextName= Context name with which to run the job. @param contextName= Context name with which to run the job.
Default = `SAS Job Execution compute context` Default = `SAS Job Execution compute context`
@param outds= The output dataset containing links (Default=work.mv_jobexecute)
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe, source: https://github.com/sasjs/core @author Allan Bowe, source: https://github.com/sasjs/core
@@ -39,6 +49,7 @@
@li mp_abort.sas @li mp_abort.sas
@li mf_getplatform.sas @li mf_getplatform.sas
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mv_getfoldermembers.sas @li mv_getfoldermembers.sas
**/ **/
@@ -48,6 +59,8 @@
,contextName=SAS Job Execution compute context ,contextName=SAS Job Execution compute context
,access_token_var=ACCESS_TOKEN ,access_token_var=ACCESS_TOKEN
,grant_type=sas_services ,grant_type=sas_services
,paramstring=0
,outds=work.mv_jobexecute
); );
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
@@ -109,11 +122,16 @@ run;
data _null_; data _null_;
file &fname0; file &fname0;
put '{"jobDefinitionUri": "'@@; length joburi contextname $128 paramstring $32765;
put "&joburi"@@; joburi=quote(trim(symget('joburi')));
put '","arguments":{"_contextName":"'@@; contextname=quote(trim(symget('contextname')));
put "&contextName"@@; paramstring=symget('paramstring');
put '"}}'; put '{"jobDefinitionUri":' joburi ;
put ' ,"arguments":{"_contextName":' contextname;
if paramstring ne "0" then do;
put ' ,' paramstring;
end;
put '}}';
run; run;
proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
@@ -125,17 +143,26 @@ proc http method='POST' in=&fname0 out=&fname1 &oauth_bearer
%end; %end;
; ;
run; run;
/*data _null_;infile &fname1;input;putlog _infile_;run;*/ %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
%do;
%mp_abort(iftrue=( data _null_;infile &fname0;input;putlog _infile_;run;
&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 data _null_;infile &fname1;input;putlog _infile_;run;
%mp_abort(mac=&sysmacroname
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) )
,mac=&sysmacroname %end;
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
) %local libref;
%let libref=%mf_getuniquelibref();
libname &libref JSON fileref=&fname1;
data &outds;
set &libref..links;
run;
/* clear refs */ /* clear refs */
filename &fname0 clear; filename &fname0 clear;
filename &fname1 clear; filename &fname1 clear;
libname &libref;
%mend; %mend;

View File

@@ -35,25 +35,24 @@
@param scopes= list of space-seperated unquoted scopes (default is openid) @param scopes= list of space-seperated unquoted scopes (default is openid)
@param grant_type= valid values are "password" or "authorization_code" (unquoted) @param grant_type= valid values are "password" or "authorization_code" (unquoted)
@param outds= the dataset to contain the registered client id and secret @param outds= the dataset to contain the registered client id and secret
@param access_token_validity= The duration of validity of the access token @param access_token_validity= The duration of validity of the access token
in seconds. A value of DEFAULT will omit the entry (and use system default) in seconds. A value of DEFAULT will omit the entry (and use system default)
@param refresh_token_validity= The duration of validity of the refresh token @param refresh_token_validity= The duration of validity of the refresh token
in seconds. A value of DEFAULT will omit the entry (and use system default) in seconds. A value of DEFAULT will omit the entry (and use system default)
@param name= A human readable name for the client @param name= A human readable name for the client
@param required_user_groups= A list of group names. If a user does not belong @param required_user_groups= A list of group names. If a user does not belong
to all the required groups, the user will not be authenticated and no tokens to all the required groups, the user will not be authenticated and no tokens
are issued to this client for that user. If this field is not specified, are issued to this client for that user. If this field is not specified,
authentication and token issuance proceeds normally. authentication and token issuance proceeds normally.
@param autoapprove= During the auth step the user can choose which scope to @param autoapprove= During the auth step the user can choose which scope to
apply. Setting this to true will autoapprove all the client scopes. apply. Setting this to true will autoapprove all the client scopes.
@param use_session= If true, access tokens issued to this client will be @param use_session= If true, access tokens issued to this client will be
associated with an HTTP session and revoked upon logout or time-out. associated with an HTTP session and revoked upon logout or time-out.
@param outjson= A dataset containing the lines of JSON submitted. Useful @param outjson= A dataset containing the lines of JSON submitted. Useful
for debugging. Default= _null_. for debugging. Default= _null_.
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas
@@ -143,7 +142,7 @@ data _null_;
if not missing(autoapprove) then autoapprove=cats(',"autoapprove":',autoapprove); if not missing(autoapprove) then autoapprove=cats(',"autoapprove":',autoapprove);
use_session=trim(symget('use_session')); use_session=trim(symget('use_session'));
if not missing(use_session) then use_session=cats(',"use_session":',use_session); if not missing(use_session) then use_session=cats(',"use_session":',use_session);
put '{' clientid ; put '{' clientid ;
put clientsecret ; put clientsecret ;
put clientname; put clientname;

View File

@@ -41,8 +41,7 @@
@param base_uri= The Viya API server location @param base_uri= The Viya API server location
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas

View File

@@ -40,8 +40,7 @@
@param refresh_token_var= The global macro variable containing the refresh token @param refresh_token_var= The global macro variable containing the refresh token
@version VIYA V.03.04 @version VIYA V.03.04
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
@source https://github.com/sasjs/core
<h4> Dependencies </h4> <h4> Dependencies </h4>
@li mp_abort.sas @li mp_abort.sas

View File

@@ -32,13 +32,13 @@
@li mf_getuser.sas @li mf_getuser.sas
@version Viya 3.3 @version Viya 3.3
@author Allan Bowe @author Allan Bowe, source: https://github.com/sasjs/core
**/ **/
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y); %macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y);
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name %global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
sasjs_tables SYS_JES_JOB_URI; sasjs_tables SYS_JES_JOB_URI;
%if %index("&_debug",log) %then %let _debug=131; %if %index("&_debug",log) %then %let _debug=131;
%local i tempds; %local i tempds;
%let action=%upcase(&action); %let action=%upcase(&action);
@@ -144,8 +144,8 @@
filename _webout temp lrecl=999999 mod; filename _webout temp lrecl=999999 mod;
%end; %end;
%else %do; %else %do;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
name="_webout.json" lrecl=999999 mod; name="_webout.json" lrecl=999999 mod;
%end; %end;
/* setup temp ref */ /* setup temp ref */