From 512f05c0b246da50524dbed75d7bfc4cd432769b Mon Sep 17 00:00:00 2001 From: munja Date: Thu, 19 May 2022 22:02:19 +0100 Subject: [PATCH] feat: creating new mx_ suite of macros! also adding new mx_getcode macro --- README.md | 92 +++--- base/mf_getplatform.sas | 10 +- base/mf_isint.sas | 2 +- base/mp_createwebservice.sas | 76 +---- base/mp_testservice.sas | 294 +---------------- build.py | 2 +- main.dox | 13 +- .../mcf_getfmttype.test.sas | 0 .../{crossplatform => base}/mcf_init.test.sas | 0 .../mcf_length.test.sas | 0 .../mcf_string2file.test.sas | 0 .../{crossplatform => base}/mf_dedup.test.sas | 0 .../mf_deletefile.test.sas | 0 .../mf_existds.test.sas | 0 .../mf_existfileref.test.sas | 0 .../mf_existfunction.test.sas | 0 .../mf_existvar.test.sas | 0 .../mf_fmtdttm.test.sas | 0 .../mf_getapploc.test.sas | 0 .../mf_getfilesize.test.sas | 0 .../mf_getfmtlist.test.sas | 0 .../mf_getfmtname.test.sas | 0 .../mf_getuniquefileref.test.sas | 0 .../mf_getuniquelibref.test.sas | 0 .../mf_getvarcount.test.sas | 0 .../mf_getvarlist.test.sas | 0 .../{crossplatform => base}/mf_isint.test.sas | 0 .../mf_islibds.test.sas | 0 .../mf_verifymacvars.test.sas | 0 .../mf_wordsinstr1andstr2.test.sas | 0 .../mf_wordsinstr1butnotstr2.test.sas | 0 .../mf_writefile.test.sas | 0 .../mp_abort.test.nofix.sas | 0 .../mp_appendfile.test.sas | 0 .../mp_applyformats.test.sas | 0 .../mp_assert.test.sas | 0 .../mp_assertcolvals.test.sas | 0 .../mp_assertdsobs.test.sas | 0 .../mp_assertscope.test.sas | 0 .../mp_base64copy.test.sas | 0 .../mp_binarycopy.test.sas | 0 .../{crossplatform => base}/mp_chop.test.sas | 0 .../mp_cntlout.test.sas | 0 .../mp_copyfolder.test.sas | 0 .../mp_coretable.test.sas | 0 .../mp_createwebservice.test.sas | 0 .../mp_deletefolder.test.sas | 0 .../mp_dirlist.test.sas | 0 .../mp_ds2cards.test.sas | 0 .../mp_ds2csv.test.sas | 0 .../mp_ds2fmtds.test.sas | 0 .../mp_ds2inserts.test.sas | 0 .../{crossplatform => base}/mp_ds2md.test.sas | 0 .../mp_ds2squeeze.test.sas | 0 .../mp_filtercheck.test.sas | 0 .../mp_filtergenerate.test.sas | 0 .../mp_filterstore.test.1.sas | 0 .../mp_filterstore.test.2.sas | 0 .../mp_filtervalidate.test.sas | 0 .../mp_getcols.test.sas | 0 .../mp_getconstraints.test.sas | 0 .../mp_getddl.test.sas | 0 .../mp_getformats.test.sas | 0 .../mp_getmaxvarlengths.test.sas | 0 .../{crossplatform => base}/mp_getpk.test.sas | 0 .../mp_gsubfile.test.sas | 0 .../mp_hashdataset.test.sas | 0 .../{crossplatform => base}/mp_init.test.sas | 0 .../mp_jsonout.test.1.sas | 0 .../mp_jsonout.test.2.sas | 0 .../mp_jsonout.test.3.sas | 0 .../mp_lib2inserts.test.sas | 0 .../mp_loadformat.test.sas | 0 .../mp_lockanytable.test.sas | 0 .../mp_lockfilecheck.test.sas | 0 .../mp_makedata.test.sas | 0 tests/{crossplatform => base}/mp_md5.test.sas | 0 .../mp_replace.test.sas | 0 .../mp_reseterror.test.sas | 0 .../mp_resetoption.test.sas | 0 .../mp_retainedkey.test.sas | 0 .../mp_searchcols.test.sas | 0 .../mp_searchdata.test.sas | 0 .../mp_sortinplace.test.sas | 0 .../mp_stackdiffs.test.sas | 0 .../mp_storediffs.test.sas | 0 .../mp_streamfile.test.sas | 0 .../mp_validatecol.test.sas | 0 .../{crossplatform => base}/mp_webin.test.sas | 0 tests/{crossplatform => base}/mp_zip.test.sas | 0 tests/xplatform/mx_getcode.test.sas | 38 +++ .../mx_testservice.test.sas} | 8 +- xplatform/mx_createwebservice.sas | 96 ++++++ xplatform/mx_getcode.sas | 57 ++++ xplatform/mx_testservice.sas | 299 ++++++++++++++++++ 95 files changed, 591 insertions(+), 396 deletions(-) rename tests/{crossplatform => base}/mcf_getfmttype.test.sas (100%) rename tests/{crossplatform => base}/mcf_init.test.sas (100%) rename tests/{crossplatform => base}/mcf_length.test.sas (100%) rename tests/{crossplatform => base}/mcf_string2file.test.sas (100%) rename tests/{crossplatform => base}/mf_dedup.test.sas (100%) rename tests/{crossplatform => base}/mf_deletefile.test.sas (100%) rename tests/{crossplatform => base}/mf_existds.test.sas (100%) rename tests/{crossplatform => base}/mf_existfileref.test.sas (100%) rename tests/{crossplatform => base}/mf_existfunction.test.sas (100%) rename tests/{crossplatform => base}/mf_existvar.test.sas (100%) rename tests/{crossplatform => base}/mf_fmtdttm.test.sas (100%) rename tests/{crossplatform => base}/mf_getapploc.test.sas (100%) rename tests/{crossplatform => base}/mf_getfilesize.test.sas (100%) rename tests/{crossplatform => base}/mf_getfmtlist.test.sas (100%) rename tests/{crossplatform => base}/mf_getfmtname.test.sas (100%) rename tests/{crossplatform => base}/mf_getuniquefileref.test.sas (100%) rename tests/{crossplatform => base}/mf_getuniquelibref.test.sas (100%) rename tests/{crossplatform => base}/mf_getvarcount.test.sas (100%) rename tests/{crossplatform => base}/mf_getvarlist.test.sas (100%) rename tests/{crossplatform => base}/mf_isint.test.sas (100%) rename tests/{crossplatform => base}/mf_islibds.test.sas (100%) rename tests/{crossplatform => base}/mf_verifymacvars.test.sas (100%) rename tests/{crossplatform => base}/mf_wordsinstr1andstr2.test.sas (100%) rename tests/{crossplatform => base}/mf_wordsinstr1butnotstr2.test.sas (100%) rename tests/{crossplatform => base}/mf_writefile.test.sas (100%) rename tests/{crossplatform => base}/mp_abort.test.nofix.sas (100%) rename tests/{crossplatform => base}/mp_appendfile.test.sas (100%) rename tests/{crossplatform => base}/mp_applyformats.test.sas (100%) rename tests/{crossplatform => base}/mp_assert.test.sas (100%) rename tests/{crossplatform => base}/mp_assertcolvals.test.sas (100%) rename tests/{crossplatform => base}/mp_assertdsobs.test.sas (100%) rename tests/{crossplatform => base}/mp_assertscope.test.sas (100%) rename tests/{crossplatform => base}/mp_base64copy.test.sas (100%) rename tests/{crossplatform => base}/mp_binarycopy.test.sas (100%) rename tests/{crossplatform => base}/mp_chop.test.sas (100%) rename tests/{crossplatform => base}/mp_cntlout.test.sas (100%) rename tests/{crossplatform => base}/mp_copyfolder.test.sas (100%) rename tests/{crossplatform => base}/mp_coretable.test.sas (100%) rename tests/{crossplatform => base}/mp_createwebservice.test.sas (100%) rename tests/{crossplatform => base}/mp_deletefolder.test.sas (100%) rename tests/{crossplatform => base}/mp_dirlist.test.sas (100%) rename tests/{crossplatform => base}/mp_ds2cards.test.sas (100%) rename tests/{crossplatform => base}/mp_ds2csv.test.sas (100%) rename tests/{crossplatform => base}/mp_ds2fmtds.test.sas (100%) rename tests/{crossplatform => base}/mp_ds2inserts.test.sas (100%) rename tests/{crossplatform => base}/mp_ds2md.test.sas (100%) rename tests/{crossplatform => base}/mp_ds2squeeze.test.sas (100%) rename tests/{crossplatform => base}/mp_filtercheck.test.sas (100%) rename tests/{crossplatform => base}/mp_filtergenerate.test.sas (100%) rename tests/{crossplatform => base}/mp_filterstore.test.1.sas (100%) rename tests/{crossplatform => base}/mp_filterstore.test.2.sas (100%) rename tests/{crossplatform => base}/mp_filtervalidate.test.sas (100%) rename tests/{crossplatform => base}/mp_getcols.test.sas (100%) rename tests/{crossplatform => base}/mp_getconstraints.test.sas (100%) rename tests/{crossplatform => base}/mp_getddl.test.sas (100%) rename tests/{crossplatform => base}/mp_getformats.test.sas (100%) rename tests/{crossplatform => base}/mp_getmaxvarlengths.test.sas (100%) rename tests/{crossplatform => base}/mp_getpk.test.sas (100%) rename tests/{crossplatform => base}/mp_gsubfile.test.sas (100%) rename tests/{crossplatform => base}/mp_hashdataset.test.sas (100%) rename tests/{crossplatform => base}/mp_init.test.sas (100%) rename tests/{crossplatform => base}/mp_jsonout.test.1.sas (100%) rename tests/{crossplatform => base}/mp_jsonout.test.2.sas (100%) rename tests/{crossplatform => base}/mp_jsonout.test.3.sas (100%) rename tests/{crossplatform => base}/mp_lib2inserts.test.sas (100%) rename tests/{crossplatform => base}/mp_loadformat.test.sas (100%) rename tests/{crossplatform => base}/mp_lockanytable.test.sas (100%) rename tests/{crossplatform => base}/mp_lockfilecheck.test.sas (100%) rename tests/{crossplatform => base}/mp_makedata.test.sas (100%) rename tests/{crossplatform => base}/mp_md5.test.sas (100%) rename tests/{crossplatform => base}/mp_replace.test.sas (100%) rename tests/{crossplatform => base}/mp_reseterror.test.sas (100%) rename tests/{crossplatform => base}/mp_resetoption.test.sas (100%) rename tests/{crossplatform => base}/mp_retainedkey.test.sas (100%) rename tests/{crossplatform => base}/mp_searchcols.test.sas (100%) rename tests/{crossplatform => base}/mp_searchdata.test.sas (100%) rename tests/{crossplatform => base}/mp_sortinplace.test.sas (100%) rename tests/{crossplatform => base}/mp_stackdiffs.test.sas (100%) rename tests/{crossplatform => base}/mp_storediffs.test.sas (100%) rename tests/{crossplatform => base}/mp_streamfile.test.sas (100%) rename tests/{crossplatform => base}/mp_validatecol.test.sas (100%) rename tests/{crossplatform => base}/mp_webin.test.sas (100%) rename tests/{crossplatform => base}/mp_zip.test.sas (100%) create mode 100644 tests/xplatform/mx_getcode.test.sas rename tests/{crossplatform/mp_testservice.test.sas => xplatform/mx_testservice.test.sas} (89%) create mode 100644 xplatform/mx_createwebservice.sas create mode 100644 xplatform/mx_getcode.sas create mode 100644 xplatform/mx_testservice.sas diff --git a/README.md b/README.md index 3fc74f0..4c5bf7f 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,14 @@ Documentation: https://core.sasjs.io ## Components -### BASE library (All Platforms) +### BASE folder (All Platforms) - OS independent - Works on all SAS Platforms - No X command - Prefixes: _mf_, _mp_ -### DDL library (All Platforms) +### DDL folder (All Platforms) - OS independent - Works on all SAS Platforms @@ -47,45 +47,13 @@ Documentation: https://core.sasjs.io This library will not be used for storing data entries (such as formats or datalines). Where this becomes necessary in the future, a new repo will be created, in order to keep the NPM bundle size down (for the benefit of those looking to embed purely macros in their applications). -### FCMP library (All Platforms) +### FCMP folder (All Platforms) - Function and macro names are identical, except for special cases - Prefixes: _mcf_ The fcmp macros are used to generate fcmp functions, and can be used with or without the `proc fcmp` wrapper. -### META library (SAS9 only) - -Macros used in SAS EBI, which connect to the metadata server. - -- OS independent -- Metadata aware -- No X command -- Prefixes: _mm_ - -### SERVER library (@sasjs/server only) -These macros are used for building applications using [@sasjs/server](https://server.sasjs.io) - an open source REST API for Desktop SAS. - -- OS independent -- @sasjs/server aware -- No X command -- Prefixes: _ms_ - -### VIYA library (Viya only) - -Macros used for interfacing with SAS Viya. - -- OS independent -- No X command -- Prefixes: _mv_, _mvf_ - -### METAX library (SAS9 only) - -- OS specific -- Metadata aware -- 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. @@ -106,13 +74,61 @@ run; - Prefixes: _ml_ +### META folder (SAS9 only) + +Macros used in SAS EBI, which connect to the metadata server. + +- OS independent +- Metadata aware +- No X command +- Prefixes: _mm_ + +### METAX folder (SAS9 only) + +- OS specific +- Metadata aware +- X command enabled +- Prefixes: _mmw_,_mmu_,_mmx_ + +### SERVER folder (@sasjs/server only) +These macros are used for building applications using [@sasjs/server](https://server.sasjs.io) - an open source REST API for Desktop SAS. + +- OS independent +- @sasjs/server aware +- No X command +- Prefixes: _ms_ + +### VIYA folder (Viya only) + +Macros used for interfacing with SAS Viya. + +- OS independent +- No X command +- Prefixes: _mv_, _mvf_ + +### XPLATFORM folder (Viya, Meta, and Server) + +Sometimes it is helpful to use a macro that can be used interchangeably regardless of the server type on which is is running (SASVIYA, SAS9, SASJS). + +- OS independent +- No X command +- Prefixes: _mx_ + ## 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: ```sas -options insert=(sasautos="/your/path/macrocore/base"); -options insert=(sasautos="/your/path/macrocore/meta"); +%let repoloc=/your/path/core; +options insert=(sasautos="&repoloc/base"); +options insert=(sasautos="&repoloc/ddl"); +options insert=(sasautos="&repoloc/fcmp"); +options insert=(sasautos="&repoloc/lua"); +options insert=(sasautos="&repoloc/meta"); +options insert=(sasautos="&repoloc/metax"); +options insert=(sasautos="&repoloc/server"); +options insert=(sasautos="&repoloc/viya"); +options insert=(sasautos="&repoloc/xplatform"); ``` The above can be done directly in your sas program, via an autoexec, or an initialisation program. @@ -142,7 +158,7 @@ filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; - _mp_ for macro procedures (which generate sas code) - _ms_ for macro procedures that will only work with [@sasjs/server](https://github.com/sasjs/server) - _mv_ for macro procedures that will only work in Viya - - _mx_ for macros that are XCMD enabled (working on both windows and unix) + - _mx_ for macros that work on Viya, SAS 9 EBI and SASjs Server - follow verb-noun convention - unix style line endings (lf) - individual lines should be no more than 80 characters long diff --git a/base/mf_getplatform.sas b/base/mf_getplatform.sas index 4d20dbd..8416686 100644 --- a/base/mf_getplatform.sas +++ b/base/mf_getplatform.sas @@ -5,8 +5,12 @@ %put %mf_getplatform(); - returns: - SASMETA (or SASVIYA) + returns one of: + + @li SASMETA + @li SASVIYA + @li SASJS + @li BASESAS @param switch the param for which to return a platform specific variable @@ -68,4 +72,4 @@ %else %if &switch=VIYARESTAPI %then %do; %mf_trimstr(%sysfunc(getoption(servicesbaseurl)),/) %end; -%mend mf_getplatform; \ No newline at end of file +%mend mf_getplatform; diff --git a/base/mf_isint.sas b/base/mf_isint.sas index 71548bb..a6019a1 100644 --- a/base/mf_isint.sas +++ b/base/mf_isint.sas @@ -33,4 +33,4 @@ %if %sysfunc(findc(%str(&val),,kd)) %then %do;0%end; %else %do;1%end; -%mend mf_isint; \ No newline at end of file +%mend mf_isint; diff --git a/base/mp_createwebservice.sas b/base/mp_createwebservice.sas index 80b4459..4be9b08 100644 --- a/base/mp_createwebservice.sas +++ b/base/mp_createwebservice.sas @@ -1,50 +1,13 @@ /** @file mp_createwebservice.sas - @brief Create a web service in SAS 9 or Viya - @details Creates a SASJS ready Stored Process in SAS 9 or Job Execution - Service in SAS Viya + @brief Create a web service in SAS 9, Viya or SASjs Server + @details This is actually a wrapper for mx_createwebservice.sas, remaining + for legacy purposes. For new apps, use mx_createwebservice.sas. -Usage: - - %* compile macros ; - filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; - %inc mc; - - %* write some code; - filename ft15f001 temp; - parmcards4; - %* fetch any data from frontend ; - %webout(FETCH) - data example1 example2; - set sashelp.class; - run; - %* send data back; - %webout(OPEN) - %webout(ARR,example1) * Array format, fast, suitable for large tables ; - %webout(OBJ,example2) * Object format, easier to work with ; - %webout(CLOSE) - ;;;; - %mp_createwebservice(path=/Public/app/common,name=appInit,replace=YES)

SAS Macros

- @li mf_getplatform.sas - @li mm_createwebservice.sas - @li ms_createwebservice.sas - @li mv_createwebservice.sas + @li mx_createwebservice.sas - @param [in,out] path= The full folder path where the service will be created - @param [in,out] name= Service name. Avoid spaces. - @param [in] desc= The description of the service (optional) - @param [in] precode= Space separated list of filerefs, pointing to the code - that needs to be attached to the beginning of the service (optional) - @param [in] code= (ft15f001) Space seperated fileref(s) of the actual code to - be added - @param [in] replace= (YES) Select YES to replace any existing service in that - location - @param [in] mDebug= (0) set to 1 to show debug messages in the log - - @version 9.2 - @author Allan Bowe **/ @@ -57,40 +20,13 @@ Usage: ,mdebug=0 )/*/STORE SOURCE*/; -%if &syscc ge 4 %then %do; - %put syscc=&syscc - &sysmacroname will not execute in this state; - %return; -%end; - -%local platform; %let platform=%mf_getplatform(); -%if &platform=SASVIYA %then %do; - %if "&path"="HOME" %then %let path=/Users/&sysuserid/My Folder; - %mv_createwebservice(path=&path + %mx_createwebservice(path=&path ,name=&name - ,code=&code ,precode=&precode + ,code=&code ,desc=&desc ,replace=&replace - ) -%end; -%else %if &platform=SASJS %then %do; - %if "&path"="HOME" %then %let path=/Users/&_sasjs_username/My Folder; - %ms_createwebservice(path=&path - ,name=&name - ,code=&code - ,precode=&precode ,mdebug=&mdebug ) -%end; -%else %do; - %if "&path"="HOME" %then %let path=/User Folders/&_METAPERSON/My Folder; - %mm_createwebservice(path=&path - ,name=&name - ,code=&code - ,precode=&precode - ,desc=&desc - ,replace=&replace - ) -%end; %mend mp_createwebservice; diff --git a/base/mp_testservice.sas b/base/mp_testservice.sas index c21e0a2..49c6f64 100644 --- a/base/mp_testservice.sas +++ b/base/mp_testservice.sas @@ -1,53 +1,11 @@ /** @file - @brief Will execute a SASjs web service on SAS 9 or Viya - @details Prepares the input files and retrieves the resulting datasets from - the response JSON. - - - - Note - the _webout fileref should NOT be assigned prior to running this macro. - - @param [in] program The _PROGRAM endpoint to test - @param [in] inputfiles=(0) A list of space seperated fileref:filename pairs as - follows: - inputfiles=inref:filename inref2:filename2 - @param [in] inputdatasets= (0) All datasets in this space seperated list are - converted into SASJS-formatted CSVs (see mp_ds2csv.sas) files and added to - the list of `inputfiles` for ingestion. The dataset will be sent with the - same name (no need for a colon modifier). - @param [in] inputparams=(0) A dataset containing name/value pairs in the - following format: - |name:$32|value:$1000| - |---|---| - |stpmacname|some value| - |mustbevalidname|can be anything, oops, %abort!!| - - @param [in] debug= (log) Provide the _debug value - @param [in] mdebug= (0) Set to 1 to provide macro debugging - @param [in] viyaresult= (WEBOUT_JSON) The Viya result type to return. For - more info, see mv_getjobresult.sas - @param [in] viyacontext= (SAS Job Execution compute context) The Viya compute - context on which to run the service - @param [out] outlib= (0) Output libref to contain the final tables. Set to - 0 if the service output is not in JSON format. - @param [out] outref= (0) Output fileref to create, to contain the full _webout - response. + @brief To be deprecated. Will execute a SASjs web service on SAS 9 or Viya + @details Use the mx_testservice.sas macro instead (documentation can be + found there)

SAS Macros

- @li mf_getplatform.sas - @li mf_getuniquefileref.sas - @li mf_getuniquename.sas - @li mp_abort.sas - @li mp_binarycopy.sas - @li mp_chop.sas - @li mp_ds2csv.sas - @li ms_testservice.sas - @li mv_getjobresult.sas - @li mv_jobflow.sas - -

Related Programs

- @li mp_testservice.test.sas + @li mx_testservice.sas @version 9.4 @author Allan Bowe @@ -65,237 +23,17 @@ viyaresult=WEBOUT_JSON, viyacontext=SAS Job Execution compute context )/*/STORE SOURCE*/; -%local dbg pcnt fref1 fref2 webref webrefpath i webcount var platform; -%if &mdebug=1 %then %do; - %put &sysmacroname entry vars:; - %put _local_; -%end; -%else %let dbg=*; -/* sanitise inputparams */ -%let pcnt=0; -%if &inputparams ne 0 %then %do; - data _null_; - set &inputparams; - if not nvalid(name,'v7') then putlog (_all_)(=); - else if name in ( - 'program','inputfiles','inputparams','debug','outlib','outref' - ) then putlog (_all_)(=); - else do; - x+1; - call symputx(name,quote(cats(value)),'l'); - call symputx(cats('pval',x),name,'l'); - call symputx('pcnt',x,'l'); - end; - run; - %mp_abort(iftrue= (%mf_nobs(&inputparams) ne &pcnt) - ,mac=&sysmacroname - ,msg=%str(Invalid values in &inputparams) - ) -%end; +%mx_testservice(&program, + inputfiles=&inputfiles, + inputdatasets=&inputdatasets, + inputparams=&inputparams, + debug=&debug, + mdebug=&mdebug, + outlib=&outlib, + outref=&outref, + viyaresult=&viyaresult, + viyacontext=&viyacontext +) -/* convert inputdatasets to filerefs */ -%if "&inputdatasets" ne "0" %then %do; - %if %quote(&inputfiles)=0 %then %let inputfiles=; - %do i=1 %to %sysfunc(countw(&inputdatasets,%str( ))); - %let var=%scan(&inputdatasets,&i,%str( )); - %local dsref&i; - %let dsref&i=%mf_getuniquefileref(); - %mp_ds2csv(&var,outref=&&dsref&i,headerformat=SASJS) - %let inputfiles=&inputfiles &&dsref&i:%scan(&var,-1,.); - %end; -%end; - -%let platform=%mf_getplatform(); -%let fref1=%mf_getuniquefileref(); -%let fref2=%mf_getuniquefileref(); -%let webref=%mf_getuniquefileref(); -%let webrefpath=%sysfunc(pathname(work))/%mf_getuniquename(); -/* mp_chop requires a physical path as input */ -filename &webref "&webrefpath"; - -%if &platform=SASMETA %then %do; - - /* parse the input files */ - %if %quote(&inputfiles) ne 0 %then %do; - %let webcount=%sysfunc(countw(&inputfiles)); - %put &=webcount; - %do i=1 %to &webcount; - %let var=%scan(&inputfiles,&i,%str( )); - %local webfref&i webname&i; - %let webref&i=%scan(&var,1,%str(:)); - %let webname&i=%scan(&var,2,%str(:)); - %put webref&i=&&webref&i; - %put webname&i=&&webname&i; - %end; - %end; - %else %let webcount=0; - - proc stp program="&program"; - inputparam _program="&program" - %do i=1 %to &webcount; - %if &webcount=1 %then %do; - _webin_fileref="&&webref&i" - _webin_name="&&webname&i" - %end; - %else %do; - _webin_fileref&i="&&webref&i" - _webin_name&i="&&webname&i" - %end; - %end; - _webin_file_count="&webcount" - _debug="&debug" - %do i=1 %to &pcnt; - /* resolve name only, proc stp fetches value */ - &&pval&i=&&&&&&pval&i - %end; - ; - %do i=1 %to &webcount; - inputfile &&webref&i; - %end; - outputfile _webout=&webref; - run; - - data _null_; - infile &webref; - file &fref1; - input; - length line $10000; - if index(_infile_,'>>weboutBEGIN<<') then do; - line=tranwrd(_infile_,'>>weboutBEGIN<<',''); - put line; - end; - else if index(_infile_,'>>weboutEND<<') then do; - line=tranwrd(_infile_,'>>weboutEND<<',''); - put line; - stop; - end; - else put _infile_; - run; - data _null_; - infile &fref1; - input; - put _infile_; - run; - %if &outlib ne 0 %then %do; - libname &outlib json (&fref1); - %end; - %if &outref ne 0 %then %do; - filename &outref temp; - %mp_binarycopy(inref=&webref,outref=&outref) - %end; - -%end; -%else %if &platform=SASVIYA %then %do; - - /* prepare inputparams */ - %local ds1; - %let ds1=%mf_getuniquename(); - %if "&inputparams" ne "0" %then %do; - proc transpose data=&inputparams out=&ds1; - id name; - var value; - run; - %end; - %else %do; - data &ds1;run; - %end; - - /* parse the input files - convert to sasjs params */ - %local webcount i var sasjs_tables; - %if %quote(&inputfiles) ne 0 %then %do; - %let webcount=%sysfunc(countw(&inputfiles)); - %put &=webcount; - %do i=1 %to &webcount; - %let var=%scan(&inputfiles,&i,%str( )); - %local webfref&i webname&i sasjs&i.data; - %let webref&i=%scan(&var,1,%str(:)); - %let webname&i=%scan(&var,2,%str(:)); - %put webref&i=&&webref&i; - %put webname&i=&&webname&i; - - %let sasjs_tables=&sasjs_tables &&webname&i; - data _null_; - infile &&webref&i lrecl=32767; - input; - if _n_=1 then call symputx("sasjs&i.data",_infile_); - else call symputx( - "sasjs&i.data",cats(symget("sasjs&i.data"),'0D0A'x,_infile_) - ); - putlog "&sysmacroname infile: " _infile_; - run; - data &ds1; - set &ds1; - length sasjs&i.data $32767 sasjs_tables $1000; - sasjs&i.data=symget("sasjs&i.data"); - sasjs_tables=symget("sasjs_tables"); - run; - %end; - %end; - %else %let webcount=0; - - data &ds1; - retain _program "&program"; - retain _contextname "&viyacontext"; - set &ds1; - putlog "&sysmacroname inputparams:"; - putlog (_all_)(=); - run; - - %mv_jobflow(inds=&ds1 - ,maxconcurrency=1 - ,outds=work.results - ,outref=&fref1 - ,mdebug=&mdebug - ) - /* show the log */ - data _null_; - infile &fref1; - input; - putlog _infile_; - run; - /* get the uri to fetch results */ - data _null_; - set work.results; - call symputx('uri',uri); - putlog "&sysmacroname: fetching results for " uri; - run; - /* fetch results from webout.json */ - %mv_getjobresult(uri=&uri, - result=&viyaresult, - outref=&outref, - outlib=&outlib, - mdebug=&mdebug - ) - -%end; -%else %if &platform=SASJS %then %do; - - %ms_testservice(&program - ,inputfiles=&inputfiles - ,inputdatasets=&inputdatasets - ,inputparams=&inputparams - ,debug=&debug - ,mdebug=&mdebug - ,outlib=&outlib - ,outref=&outref - ) - -%end; -%else %do; - %put %str(ERR)OR: Unrecognised platform: &platform; -%end; - -%if &mdebug=0 %then %do; - filename &fref1 clear; - %if &platform ne SASJS %then %do; - filename &fref2 clear; - filename &webref clear; - %end; -%end; -%else %do; - %put &sysmacroname exit vars:; - %put _local_; -%end; - -%mend mp_testservice; \ No newline at end of file +%mend mp_testservice; diff --git a/build.py b/build.py index c4ab568..5767276 100755 --- a/build.py +++ b/build.py @@ -102,7 +102,7 @@ options noquotelenmax; """ f = open('all.sas', "w") # r / r+ / rb / rb+ / w / wb f.write(header) -folders = ['base', 'ddl', 'meta', 'metax', 'server', 'viya', 'lua', 'fcmp'] +folders = ['base', 'ddl', 'meta', 'metax', 'server', 'viya', 'lua', 'fcmp', 'xplatform'] for folder in folders: filenames = [fn for fn in Path( './' + folder).iterdir() if fn.match("*.sas")] diff --git a/main.dox b/main.dox index 33459d7..1d4a2cb 100644 --- a/main.dox +++ b/main.dox @@ -103,4 +103,15 @@ * No X command * Prefixes: _mddl_ - */ \ No newline at end of file + */ + +/*! \dir xplatform + * \brief Cross Platform, works on all SAS servers (Viya, EBI, SASjs) + * \details Useful when you need to run a single piece of code against Viya, + SAS 9 with metadata, or SASjs on Base SAS. + + * OS independent + * No X command + * Prefixes: _mx_ + + */ diff --git a/tests/crossplatform/mcf_getfmttype.test.sas b/tests/base/mcf_getfmttype.test.sas similarity index 100% rename from tests/crossplatform/mcf_getfmttype.test.sas rename to tests/base/mcf_getfmttype.test.sas diff --git a/tests/crossplatform/mcf_init.test.sas b/tests/base/mcf_init.test.sas similarity index 100% rename from tests/crossplatform/mcf_init.test.sas rename to tests/base/mcf_init.test.sas diff --git a/tests/crossplatform/mcf_length.test.sas b/tests/base/mcf_length.test.sas similarity index 100% rename from tests/crossplatform/mcf_length.test.sas rename to tests/base/mcf_length.test.sas diff --git a/tests/crossplatform/mcf_string2file.test.sas b/tests/base/mcf_string2file.test.sas similarity index 100% rename from tests/crossplatform/mcf_string2file.test.sas rename to tests/base/mcf_string2file.test.sas diff --git a/tests/crossplatform/mf_dedup.test.sas b/tests/base/mf_dedup.test.sas similarity index 100% rename from tests/crossplatform/mf_dedup.test.sas rename to tests/base/mf_dedup.test.sas diff --git a/tests/crossplatform/mf_deletefile.test.sas b/tests/base/mf_deletefile.test.sas similarity index 100% rename from tests/crossplatform/mf_deletefile.test.sas rename to tests/base/mf_deletefile.test.sas diff --git a/tests/crossplatform/mf_existds.test.sas b/tests/base/mf_existds.test.sas similarity index 100% rename from tests/crossplatform/mf_existds.test.sas rename to tests/base/mf_existds.test.sas diff --git a/tests/crossplatform/mf_existfileref.test.sas b/tests/base/mf_existfileref.test.sas similarity index 100% rename from tests/crossplatform/mf_existfileref.test.sas rename to tests/base/mf_existfileref.test.sas diff --git a/tests/crossplatform/mf_existfunction.test.sas b/tests/base/mf_existfunction.test.sas similarity index 100% rename from tests/crossplatform/mf_existfunction.test.sas rename to tests/base/mf_existfunction.test.sas diff --git a/tests/crossplatform/mf_existvar.test.sas b/tests/base/mf_existvar.test.sas similarity index 100% rename from tests/crossplatform/mf_existvar.test.sas rename to tests/base/mf_existvar.test.sas diff --git a/tests/crossplatform/mf_fmtdttm.test.sas b/tests/base/mf_fmtdttm.test.sas similarity index 100% rename from tests/crossplatform/mf_fmtdttm.test.sas rename to tests/base/mf_fmtdttm.test.sas diff --git a/tests/crossplatform/mf_getapploc.test.sas b/tests/base/mf_getapploc.test.sas similarity index 100% rename from tests/crossplatform/mf_getapploc.test.sas rename to tests/base/mf_getapploc.test.sas diff --git a/tests/crossplatform/mf_getfilesize.test.sas b/tests/base/mf_getfilesize.test.sas similarity index 100% rename from tests/crossplatform/mf_getfilesize.test.sas rename to tests/base/mf_getfilesize.test.sas diff --git a/tests/crossplatform/mf_getfmtlist.test.sas b/tests/base/mf_getfmtlist.test.sas similarity index 100% rename from tests/crossplatform/mf_getfmtlist.test.sas rename to tests/base/mf_getfmtlist.test.sas diff --git a/tests/crossplatform/mf_getfmtname.test.sas b/tests/base/mf_getfmtname.test.sas similarity index 100% rename from tests/crossplatform/mf_getfmtname.test.sas rename to tests/base/mf_getfmtname.test.sas diff --git a/tests/crossplatform/mf_getuniquefileref.test.sas b/tests/base/mf_getuniquefileref.test.sas similarity index 100% rename from tests/crossplatform/mf_getuniquefileref.test.sas rename to tests/base/mf_getuniquefileref.test.sas diff --git a/tests/crossplatform/mf_getuniquelibref.test.sas b/tests/base/mf_getuniquelibref.test.sas similarity index 100% rename from tests/crossplatform/mf_getuniquelibref.test.sas rename to tests/base/mf_getuniquelibref.test.sas diff --git a/tests/crossplatform/mf_getvarcount.test.sas b/tests/base/mf_getvarcount.test.sas similarity index 100% rename from tests/crossplatform/mf_getvarcount.test.sas rename to tests/base/mf_getvarcount.test.sas diff --git a/tests/crossplatform/mf_getvarlist.test.sas b/tests/base/mf_getvarlist.test.sas similarity index 100% rename from tests/crossplatform/mf_getvarlist.test.sas rename to tests/base/mf_getvarlist.test.sas diff --git a/tests/crossplatform/mf_isint.test.sas b/tests/base/mf_isint.test.sas similarity index 100% rename from tests/crossplatform/mf_isint.test.sas rename to tests/base/mf_isint.test.sas diff --git a/tests/crossplatform/mf_islibds.test.sas b/tests/base/mf_islibds.test.sas similarity index 100% rename from tests/crossplatform/mf_islibds.test.sas rename to tests/base/mf_islibds.test.sas diff --git a/tests/crossplatform/mf_verifymacvars.test.sas b/tests/base/mf_verifymacvars.test.sas similarity index 100% rename from tests/crossplatform/mf_verifymacvars.test.sas rename to tests/base/mf_verifymacvars.test.sas diff --git a/tests/crossplatform/mf_wordsinstr1andstr2.test.sas b/tests/base/mf_wordsinstr1andstr2.test.sas similarity index 100% rename from tests/crossplatform/mf_wordsinstr1andstr2.test.sas rename to tests/base/mf_wordsinstr1andstr2.test.sas diff --git a/tests/crossplatform/mf_wordsinstr1butnotstr2.test.sas b/tests/base/mf_wordsinstr1butnotstr2.test.sas similarity index 100% rename from tests/crossplatform/mf_wordsinstr1butnotstr2.test.sas rename to tests/base/mf_wordsinstr1butnotstr2.test.sas diff --git a/tests/crossplatform/mf_writefile.test.sas b/tests/base/mf_writefile.test.sas similarity index 100% rename from tests/crossplatform/mf_writefile.test.sas rename to tests/base/mf_writefile.test.sas diff --git a/tests/crossplatform/mp_abort.test.nofix.sas b/tests/base/mp_abort.test.nofix.sas similarity index 100% rename from tests/crossplatform/mp_abort.test.nofix.sas rename to tests/base/mp_abort.test.nofix.sas diff --git a/tests/crossplatform/mp_appendfile.test.sas b/tests/base/mp_appendfile.test.sas similarity index 100% rename from tests/crossplatform/mp_appendfile.test.sas rename to tests/base/mp_appendfile.test.sas diff --git a/tests/crossplatform/mp_applyformats.test.sas b/tests/base/mp_applyformats.test.sas similarity index 100% rename from tests/crossplatform/mp_applyformats.test.sas rename to tests/base/mp_applyformats.test.sas diff --git a/tests/crossplatform/mp_assert.test.sas b/tests/base/mp_assert.test.sas similarity index 100% rename from tests/crossplatform/mp_assert.test.sas rename to tests/base/mp_assert.test.sas diff --git a/tests/crossplatform/mp_assertcolvals.test.sas b/tests/base/mp_assertcolvals.test.sas similarity index 100% rename from tests/crossplatform/mp_assertcolvals.test.sas rename to tests/base/mp_assertcolvals.test.sas diff --git a/tests/crossplatform/mp_assertdsobs.test.sas b/tests/base/mp_assertdsobs.test.sas similarity index 100% rename from tests/crossplatform/mp_assertdsobs.test.sas rename to tests/base/mp_assertdsobs.test.sas diff --git a/tests/crossplatform/mp_assertscope.test.sas b/tests/base/mp_assertscope.test.sas similarity index 100% rename from tests/crossplatform/mp_assertscope.test.sas rename to tests/base/mp_assertscope.test.sas diff --git a/tests/crossplatform/mp_base64copy.test.sas b/tests/base/mp_base64copy.test.sas similarity index 100% rename from tests/crossplatform/mp_base64copy.test.sas rename to tests/base/mp_base64copy.test.sas diff --git a/tests/crossplatform/mp_binarycopy.test.sas b/tests/base/mp_binarycopy.test.sas similarity index 100% rename from tests/crossplatform/mp_binarycopy.test.sas rename to tests/base/mp_binarycopy.test.sas diff --git a/tests/crossplatform/mp_chop.test.sas b/tests/base/mp_chop.test.sas similarity index 100% rename from tests/crossplatform/mp_chop.test.sas rename to tests/base/mp_chop.test.sas diff --git a/tests/crossplatform/mp_cntlout.test.sas b/tests/base/mp_cntlout.test.sas similarity index 100% rename from tests/crossplatform/mp_cntlout.test.sas rename to tests/base/mp_cntlout.test.sas diff --git a/tests/crossplatform/mp_copyfolder.test.sas b/tests/base/mp_copyfolder.test.sas similarity index 100% rename from tests/crossplatform/mp_copyfolder.test.sas rename to tests/base/mp_copyfolder.test.sas diff --git a/tests/crossplatform/mp_coretable.test.sas b/tests/base/mp_coretable.test.sas similarity index 100% rename from tests/crossplatform/mp_coretable.test.sas rename to tests/base/mp_coretable.test.sas diff --git a/tests/crossplatform/mp_createwebservice.test.sas b/tests/base/mp_createwebservice.test.sas similarity index 100% rename from tests/crossplatform/mp_createwebservice.test.sas rename to tests/base/mp_createwebservice.test.sas diff --git a/tests/crossplatform/mp_deletefolder.test.sas b/tests/base/mp_deletefolder.test.sas similarity index 100% rename from tests/crossplatform/mp_deletefolder.test.sas rename to tests/base/mp_deletefolder.test.sas diff --git a/tests/crossplatform/mp_dirlist.test.sas b/tests/base/mp_dirlist.test.sas similarity index 100% rename from tests/crossplatform/mp_dirlist.test.sas rename to tests/base/mp_dirlist.test.sas diff --git a/tests/crossplatform/mp_ds2cards.test.sas b/tests/base/mp_ds2cards.test.sas similarity index 100% rename from tests/crossplatform/mp_ds2cards.test.sas rename to tests/base/mp_ds2cards.test.sas diff --git a/tests/crossplatform/mp_ds2csv.test.sas b/tests/base/mp_ds2csv.test.sas similarity index 100% rename from tests/crossplatform/mp_ds2csv.test.sas rename to tests/base/mp_ds2csv.test.sas diff --git a/tests/crossplatform/mp_ds2fmtds.test.sas b/tests/base/mp_ds2fmtds.test.sas similarity index 100% rename from tests/crossplatform/mp_ds2fmtds.test.sas rename to tests/base/mp_ds2fmtds.test.sas diff --git a/tests/crossplatform/mp_ds2inserts.test.sas b/tests/base/mp_ds2inserts.test.sas similarity index 100% rename from tests/crossplatform/mp_ds2inserts.test.sas rename to tests/base/mp_ds2inserts.test.sas diff --git a/tests/crossplatform/mp_ds2md.test.sas b/tests/base/mp_ds2md.test.sas similarity index 100% rename from tests/crossplatform/mp_ds2md.test.sas rename to tests/base/mp_ds2md.test.sas diff --git a/tests/crossplatform/mp_ds2squeeze.test.sas b/tests/base/mp_ds2squeeze.test.sas similarity index 100% rename from tests/crossplatform/mp_ds2squeeze.test.sas rename to tests/base/mp_ds2squeeze.test.sas diff --git a/tests/crossplatform/mp_filtercheck.test.sas b/tests/base/mp_filtercheck.test.sas similarity index 100% rename from tests/crossplatform/mp_filtercheck.test.sas rename to tests/base/mp_filtercheck.test.sas diff --git a/tests/crossplatform/mp_filtergenerate.test.sas b/tests/base/mp_filtergenerate.test.sas similarity index 100% rename from tests/crossplatform/mp_filtergenerate.test.sas rename to tests/base/mp_filtergenerate.test.sas diff --git a/tests/crossplatform/mp_filterstore.test.1.sas b/tests/base/mp_filterstore.test.1.sas similarity index 100% rename from tests/crossplatform/mp_filterstore.test.1.sas rename to tests/base/mp_filterstore.test.1.sas diff --git a/tests/crossplatform/mp_filterstore.test.2.sas b/tests/base/mp_filterstore.test.2.sas similarity index 100% rename from tests/crossplatform/mp_filterstore.test.2.sas rename to tests/base/mp_filterstore.test.2.sas diff --git a/tests/crossplatform/mp_filtervalidate.test.sas b/tests/base/mp_filtervalidate.test.sas similarity index 100% rename from tests/crossplatform/mp_filtervalidate.test.sas rename to tests/base/mp_filtervalidate.test.sas diff --git a/tests/crossplatform/mp_getcols.test.sas b/tests/base/mp_getcols.test.sas similarity index 100% rename from tests/crossplatform/mp_getcols.test.sas rename to tests/base/mp_getcols.test.sas diff --git a/tests/crossplatform/mp_getconstraints.test.sas b/tests/base/mp_getconstraints.test.sas similarity index 100% rename from tests/crossplatform/mp_getconstraints.test.sas rename to tests/base/mp_getconstraints.test.sas diff --git a/tests/crossplatform/mp_getddl.test.sas b/tests/base/mp_getddl.test.sas similarity index 100% rename from tests/crossplatform/mp_getddl.test.sas rename to tests/base/mp_getddl.test.sas diff --git a/tests/crossplatform/mp_getformats.test.sas b/tests/base/mp_getformats.test.sas similarity index 100% rename from tests/crossplatform/mp_getformats.test.sas rename to tests/base/mp_getformats.test.sas diff --git a/tests/crossplatform/mp_getmaxvarlengths.test.sas b/tests/base/mp_getmaxvarlengths.test.sas similarity index 100% rename from tests/crossplatform/mp_getmaxvarlengths.test.sas rename to tests/base/mp_getmaxvarlengths.test.sas diff --git a/tests/crossplatform/mp_getpk.test.sas b/tests/base/mp_getpk.test.sas similarity index 100% rename from tests/crossplatform/mp_getpk.test.sas rename to tests/base/mp_getpk.test.sas diff --git a/tests/crossplatform/mp_gsubfile.test.sas b/tests/base/mp_gsubfile.test.sas similarity index 100% rename from tests/crossplatform/mp_gsubfile.test.sas rename to tests/base/mp_gsubfile.test.sas diff --git a/tests/crossplatform/mp_hashdataset.test.sas b/tests/base/mp_hashdataset.test.sas similarity index 100% rename from tests/crossplatform/mp_hashdataset.test.sas rename to tests/base/mp_hashdataset.test.sas diff --git a/tests/crossplatform/mp_init.test.sas b/tests/base/mp_init.test.sas similarity index 100% rename from tests/crossplatform/mp_init.test.sas rename to tests/base/mp_init.test.sas diff --git a/tests/crossplatform/mp_jsonout.test.1.sas b/tests/base/mp_jsonout.test.1.sas similarity index 100% rename from tests/crossplatform/mp_jsonout.test.1.sas rename to tests/base/mp_jsonout.test.1.sas diff --git a/tests/crossplatform/mp_jsonout.test.2.sas b/tests/base/mp_jsonout.test.2.sas similarity index 100% rename from tests/crossplatform/mp_jsonout.test.2.sas rename to tests/base/mp_jsonout.test.2.sas diff --git a/tests/crossplatform/mp_jsonout.test.3.sas b/tests/base/mp_jsonout.test.3.sas similarity index 100% rename from tests/crossplatform/mp_jsonout.test.3.sas rename to tests/base/mp_jsonout.test.3.sas diff --git a/tests/crossplatform/mp_lib2inserts.test.sas b/tests/base/mp_lib2inserts.test.sas similarity index 100% rename from tests/crossplatform/mp_lib2inserts.test.sas rename to tests/base/mp_lib2inserts.test.sas diff --git a/tests/crossplatform/mp_loadformat.test.sas b/tests/base/mp_loadformat.test.sas similarity index 100% rename from tests/crossplatform/mp_loadformat.test.sas rename to tests/base/mp_loadformat.test.sas diff --git a/tests/crossplatform/mp_lockanytable.test.sas b/tests/base/mp_lockanytable.test.sas similarity index 100% rename from tests/crossplatform/mp_lockanytable.test.sas rename to tests/base/mp_lockanytable.test.sas diff --git a/tests/crossplatform/mp_lockfilecheck.test.sas b/tests/base/mp_lockfilecheck.test.sas similarity index 100% rename from tests/crossplatform/mp_lockfilecheck.test.sas rename to tests/base/mp_lockfilecheck.test.sas diff --git a/tests/crossplatform/mp_makedata.test.sas b/tests/base/mp_makedata.test.sas similarity index 100% rename from tests/crossplatform/mp_makedata.test.sas rename to tests/base/mp_makedata.test.sas diff --git a/tests/crossplatform/mp_md5.test.sas b/tests/base/mp_md5.test.sas similarity index 100% rename from tests/crossplatform/mp_md5.test.sas rename to tests/base/mp_md5.test.sas diff --git a/tests/crossplatform/mp_replace.test.sas b/tests/base/mp_replace.test.sas similarity index 100% rename from tests/crossplatform/mp_replace.test.sas rename to tests/base/mp_replace.test.sas diff --git a/tests/crossplatform/mp_reseterror.test.sas b/tests/base/mp_reseterror.test.sas similarity index 100% rename from tests/crossplatform/mp_reseterror.test.sas rename to tests/base/mp_reseterror.test.sas diff --git a/tests/crossplatform/mp_resetoption.test.sas b/tests/base/mp_resetoption.test.sas similarity index 100% rename from tests/crossplatform/mp_resetoption.test.sas rename to tests/base/mp_resetoption.test.sas diff --git a/tests/crossplatform/mp_retainedkey.test.sas b/tests/base/mp_retainedkey.test.sas similarity index 100% rename from tests/crossplatform/mp_retainedkey.test.sas rename to tests/base/mp_retainedkey.test.sas diff --git a/tests/crossplatform/mp_searchcols.test.sas b/tests/base/mp_searchcols.test.sas similarity index 100% rename from tests/crossplatform/mp_searchcols.test.sas rename to tests/base/mp_searchcols.test.sas diff --git a/tests/crossplatform/mp_searchdata.test.sas b/tests/base/mp_searchdata.test.sas similarity index 100% rename from tests/crossplatform/mp_searchdata.test.sas rename to tests/base/mp_searchdata.test.sas diff --git a/tests/crossplatform/mp_sortinplace.test.sas b/tests/base/mp_sortinplace.test.sas similarity index 100% rename from tests/crossplatform/mp_sortinplace.test.sas rename to tests/base/mp_sortinplace.test.sas diff --git a/tests/crossplatform/mp_stackdiffs.test.sas b/tests/base/mp_stackdiffs.test.sas similarity index 100% rename from tests/crossplatform/mp_stackdiffs.test.sas rename to tests/base/mp_stackdiffs.test.sas diff --git a/tests/crossplatform/mp_storediffs.test.sas b/tests/base/mp_storediffs.test.sas similarity index 100% rename from tests/crossplatform/mp_storediffs.test.sas rename to tests/base/mp_storediffs.test.sas diff --git a/tests/crossplatform/mp_streamfile.test.sas b/tests/base/mp_streamfile.test.sas similarity index 100% rename from tests/crossplatform/mp_streamfile.test.sas rename to tests/base/mp_streamfile.test.sas diff --git a/tests/crossplatform/mp_validatecol.test.sas b/tests/base/mp_validatecol.test.sas similarity index 100% rename from tests/crossplatform/mp_validatecol.test.sas rename to tests/base/mp_validatecol.test.sas diff --git a/tests/crossplatform/mp_webin.test.sas b/tests/base/mp_webin.test.sas similarity index 100% rename from tests/crossplatform/mp_webin.test.sas rename to tests/base/mp_webin.test.sas diff --git a/tests/crossplatform/mp_zip.test.sas b/tests/base/mp_zip.test.sas similarity index 100% rename from tests/crossplatform/mp_zip.test.sas rename to tests/base/mp_zip.test.sas diff --git a/tests/xplatform/mx_getcode.test.sas b/tests/xplatform/mx_getcode.test.sas new file mode 100644 index 0000000..7e4cae2 --- /dev/null +++ b/tests/xplatform/mx_getcode.test.sas @@ -0,0 +1,38 @@ +/** + @file + @brief Testing mx_getcode.test.sas macro + + Be sure to run %let mcTestAppLoc=/Public/temp/macrocore; when + running in Studio + +

SAS Macros

+ @li mf_uid.sas + @li mp_assert.sas + @li mx_createwebservice.sas + @li mx_getcode.sas + @li mx_testservice.sas + +**/ + +/* first create a service */ + +%let item=%mf_uid();; + +%global test1; +%let test1=FAIL; + +filename ft15f001 temp; +parmcards4; + %let test1=SUCCESS; +;;;; +%mx_createwebservice(path=&mcTestAppLoc/temp,name=&item) + +%mx_getcode(&mcTestAppLoc/temp/&item,testref1) + +%inc testref1/lrecl=1000; + +%mp_assert( + iftrue=(&test1=SUCCESS), + desc=code was successfully fetched, + outds=work.test_results +) diff --git a/tests/crossplatform/mp_testservice.test.sas b/tests/xplatform/mx_testservice.test.sas similarity index 89% rename from tests/crossplatform/mp_testservice.test.sas rename to tests/xplatform/mx_testservice.test.sas index d52cefc..c2b2db4 100644 --- a/tests/crossplatform/mp_testservice.test.sas +++ b/tests/xplatform/mx_testservice.test.sas @@ -1,13 +1,13 @@ /** @file - @brief Testing mp_testservice.sas macro + @brief Testing mx_testservice.sas macro Be sure to run %let mcTestAppLoc=/Public/temp/macrocore; when runnin in Studio

SAS Macros

@li mp_createwebservice.sas - @li mp_testservice.sas + @li mx_testservice.sas @li mp_assert.sas **/ @@ -29,7 +29,7 @@ parmcards4; %mend x; %x() %webout(CLOSE) ;;;; -%mp_createwebservice(path=&mcTestAppLoc/services,name=sendObj) +%mx_createwebservice(path=&mcTestAppLoc/services,name=sendObj) %mp_assert( iftrue=(&syscc=0), @@ -48,7 +48,7 @@ data work.somedata1 work.somedata2; output; run; -%mp_testservice(&mcTestAppLoc/services/sendObj, +%mx_testservice(&mcTestAppLoc/services/sendObj, inputdatasets=work.somedata1 work.somedata2, debug=log, mdebug=1, diff --git a/xplatform/mx_createwebservice.sas b/xplatform/mx_createwebservice.sas new file mode 100644 index 0000000..a11de55 --- /dev/null +++ b/xplatform/mx_createwebservice.sas @@ -0,0 +1,96 @@ +/** + @file mx_createwebservice.sas + @brief Create a web service in SAS 9, Viya or SASjs + @details Creates a SASJS ready Stored Process in SAS 9, a Job Execution + Service in SAS Viya, and a Stored Program on SASjs Server + +Usage: + + %* compile macros ; + filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; + %inc mc; + + %* write some code; + filename ft15f001 temp; + parmcards4; + %* fetch any data from frontend ; + %webout(FETCH) + data example1 example2; + set sashelp.class; + run; + %* send data back; + %webout(OPEN) + %webout(ARR,example1) * Array format, fast, suitable for large tables ; + %webout(OBJ,example2) * Object format, easier to work with ; + %webout(CLOSE) + ;;;; + %mp_createwebservice(path=/Public/app/common,name=appInit,replace=YES) + +

SAS Macros

+ @li mf_getplatform.sas + @li mm_createwebservice.sas + @li ms_createwebservice.sas + @li mv_createwebservice.sas + + @param [in,out] path= The full folder path where the service will be created + @param [in,out] name= Service name. Avoid spaces. + @param [in] desc= The description of the service (optional) + @param [in] precode= Space separated list of filerefs, pointing to the code + that needs to be attached to the beginning of the service (optional) + @param [in] code= (ft15f001) Space seperated fileref(s) of the actual code to + be added + @param [in] replace= (YES) Select YES to replace any existing service in that + location + @param [in] mDebug= (0) set to 1 to show debug messages in the log + + @version 9.2 + @author Allan Bowe + +**/ + +%macro mx_createwebservice(path=HOME + ,name=initService + ,precode= + ,code=ft15f001 + ,desc=This service was created by the mp_createwebservice macro + ,replace=YES + ,mdebug=0 +)/*/STORE SOURCE*/; + +%if &syscc ge 4 %then %do; + %put syscc=&syscc - &sysmacroname will not execute in this state; + %return; +%end; + +%local platform; %let platform=%mf_getplatform(); +%if &platform=SASVIYA %then %do; + %if "&path"="HOME" %then %let path=/Users/&sysuserid/My Folder; + %mv_createwebservice(path=&path + ,name=&name + ,code=&code + ,precode=&precode + ,desc=&desc + ,replace=&replace + ) +%end; +%else %if &platform=SASJS %then %do; + %if "&path"="HOME" %then %let path=/Users/&_sasjs_username/My Folder; + %ms_createwebservice(path=&path + ,name=&name + ,code=&code + ,precode=&precode + ,mdebug=&mdebug + ) +%end; +%else %do; + %if "&path"="HOME" %then %let path=/User Folders/&_METAPERSON/My Folder; + %mm_createwebservice(path=&path + ,name=&name + ,code=&code + ,precode=&precode + ,desc=&desc + ,replace=&replace + ) +%end; + +%mend mx_createwebservice; diff --git a/xplatform/mx_getcode.sas b/xplatform/mx_getcode.sas new file mode 100644 index 0000000..ee689a6 --- /dev/null +++ b/xplatform/mx_getcode.sas @@ -0,0 +1,57 @@ +/** + @file + @brief Fetches code from Viya Job, SAS 9 STP, or SASjs Server STP + @details When building applications that run on multiple flavours of SAS, it + is convenient to use a single macro (like this one) to fetch the source + code from a Viya Job, SAS 9 Stored Process, or SASjs Stored Program. + + The alternative would be to compile a generic macro in target-specific + folders (SASVIYA, SAS9 and SASJS). This avoids compiling unnecessary macros + at the expense of a more complex sasjsconfig.json setup. + + + @param [in] loc The full path to the Viya Job, SAS 9 Stored Process or SASjs + Stored Program in Drive or Metadata, WITHOUT the .sas extension (SASjs only) + @param [out] outref= (0) The fileref to create, which will contain the source + code. + +

SAS Macros

+ @li mf_getplatform.sas + @li mf_getuniquename.sas + @li mm_getstpcode.sas + @li ms_getfile.sas + + @author Allan Bowe + +**/ + +%macro mx_getcode(loc,outref=0 +)/*/STORE SOURCE*/; + +%local platform name shortloc; +%let platform=%mf_getplatform(); + +%if &platform=SASJS %then %do; + %ms_getfile(&loc..sas, outref=&outref) +%end; +%else %if &platform=SAS9 %then %do; + %mm_getstpcode(tree=&loc,outloc=&outref) +%end; +%else %if &platform=SASVIYA %then %do; + /* extract name & path from &loc */ + data _null_; + loc=symget('loc'); + name=scan(loc,-1,'/'); + shortloc=substr(loc,1,length(loc)-length(name)-1); + call symputx('name',name,'l'); + call symputx('shortloc',shortloc,'l'); + run; + %mv_getjobcode( + path=&shortloc, + name=&name, + outref=&outref + ) +%end; +%else %put &sysmacroname: &platform is unsupported!!!; + +%mend mx_getcode; diff --git a/xplatform/mx_testservice.sas b/xplatform/mx_testservice.sas new file mode 100644 index 0000000..6a089d3 --- /dev/null +++ b/xplatform/mx_testservice.sas @@ -0,0 +1,299 @@ +/** + @file + @brief Will execute a SASjs web service on SAS 9, Viya or SASjs Server + @details Prepares the input files and retrieves the resulting datasets from + the response JSON. + + Note - the _webout fileref should NOT be assigned prior to running this macro. + + @param [in] program The _PROGRAM endpoint to test + @param [in] inputfiles=(0) A list of space seperated fileref:filename pairs as + follows: + inputfiles=inref:filename inref2:filename2 + @param [in] inputdatasets= (0) All datasets in this space seperated list are + converted into SASJS-formatted CSVs (see mp_ds2csv.sas) files and added to + the list of `inputfiles` for ingestion. The dataset will be sent with the + same name (no need for a colon modifier). + @param [in] inputparams=(0) A dataset containing name/value pairs in the + following format: + |name:$32|value:$1000| + |---|---| + |stpmacname|some value| + |mustbevalidname|can be anything, oops, %abort!!| + + @param [in] debug= (log) Provide the _debug value + @param [in] mdebug= (0) Set to 1 to provide macro debugging + @param [in] viyaresult= (WEBOUT_JSON) The Viya result type to return. For + more info, see mv_getjobresult.sas + @param [in] viyacontext= (SAS Job Execution compute context) The Viya compute + context on which to run the service + @param [out] outlib= (0) Output libref to contain the final tables. Set to + 0 if the service output is not in JSON format. + @param [out] outref= (0) Output fileref to create, to contain the full _webout + response. + +

SAS Macros

+ @li mf_getplatform.sas + @li mf_getuniquefileref.sas + @li mf_getuniquename.sas + @li mp_abort.sas + @li mp_binarycopy.sas + @li mp_chop.sas + @li mp_ds2csv.sas + @li ms_testservice.sas + @li mv_getjobresult.sas + @li mv_jobflow.sas + +

Related Programs

+ @li mx_testservice.test.sas + + @version 9.4 + @author Allan Bowe + +**/ + +%macro mx_testservice(program, + inputfiles=0, + inputdatasets=0, + inputparams=0, + debug=log, + mdebug=0, + outlib=0, + outref=0, + viyaresult=WEBOUT_JSON, + viyacontext=SAS Job Execution compute context +); +%local dbg pcnt fref1 fref2 webref webrefpath i webcount var platform; +%if &mdebug=1 %then %do; + %put &sysmacroname entry vars:; + %put _local_; +%end; +%else %let dbg=*; + +/* sanitise inputparams */ +%let pcnt=0; +%if &inputparams ne 0 %then %do; + data _null_; + set &inputparams; + if not nvalid(name,'v7') then putlog (_all_)(=); + else if name in ( + 'program','inputfiles','inputparams','debug','outlib','outref' + ) then putlog (_all_)(=); + else do; + x+1; + call symputx(name,quote(cats(value)),'l'); + call symputx(cats('pval',x),name,'l'); + call symputx('pcnt',x,'l'); + end; + run; + %mp_abort(iftrue= (%mf_nobs(&inputparams) ne &pcnt) + ,mac=&sysmacroname + ,msg=%str(Invalid values in &inputparams) + ) +%end; + +/* convert inputdatasets to filerefs */ +%if "&inputdatasets" ne "0" %then %do; + %if %quote(&inputfiles)=0 %then %let inputfiles=; + %do i=1 %to %sysfunc(countw(&inputdatasets,%str( ))); + %let var=%scan(&inputdatasets,&i,%str( )); + %local dsref&i; + %let dsref&i=%mf_getuniquefileref(); + %mp_ds2csv(&var,outref=&&dsref&i,headerformat=SASJS) + %let inputfiles=&inputfiles &&dsref&i:%scan(&var,-1,.); + %end; +%end; + +%let platform=%mf_getplatform(); +%let fref1=%mf_getuniquefileref(); +%let fref2=%mf_getuniquefileref(); +%let webref=%mf_getuniquefileref(); +%let webrefpath=%sysfunc(pathname(work))/%mf_getuniquename(); +/* mp_chop requires a physical path as input */ +filename &webref "&webrefpath"; + +%if &platform=SASMETA %then %do; + + /* parse the input files */ + %if %quote(&inputfiles) ne 0 %then %do; + %let webcount=%sysfunc(countw(&inputfiles)); + %put &=webcount; + %do i=1 %to &webcount; + %let var=%scan(&inputfiles,&i,%str( )); + %local webfref&i webname&i; + %let webref&i=%scan(&var,1,%str(:)); + %let webname&i=%scan(&var,2,%str(:)); + %put webref&i=&&webref&i; + %put webname&i=&&webname&i; + %end; + %end; + %else %let webcount=0; + + proc stp program="&program"; + inputparam _program="&program" + %do i=1 %to &webcount; + %if &webcount=1 %then %do; + _webin_fileref="&&webref&i" + _webin_name="&&webname&i" + %end; + %else %do; + _webin_fileref&i="&&webref&i" + _webin_name&i="&&webname&i" + %end; + %end; + _webin_file_count="&webcount" + _debug="&debug" + %do i=1 %to &pcnt; + /* resolve name only, proc stp fetches value */ + &&pval&i=&&&&&&pval&i + %end; + ; + %do i=1 %to &webcount; + inputfile &&webref&i; + %end; + outputfile _webout=&webref; + run; + + data _null_; + infile &webref; + file &fref1; + input; + length line $10000; + if index(_infile_,'>>weboutBEGIN<<') then do; + line=tranwrd(_infile_,'>>weboutBEGIN<<',''); + put line; + end; + else if index(_infile_,'>>weboutEND<<') then do; + line=tranwrd(_infile_,'>>weboutEND<<',''); + put line; + stop; + end; + else put _infile_; + run; + data _null_; + infile &fref1; + input; + put _infile_; + run; + %if &outlib ne 0 %then %do; + libname &outlib json (&fref1); + %end; + %if &outref ne 0 %then %do; + filename &outref temp; + %mp_binarycopy(inref=&webref,outref=&outref) + %end; + +%end; +%else %if &platform=SASVIYA %then %do; + + /* prepare inputparams */ + %local ds1; + %let ds1=%mf_getuniquename(); + %if "&inputparams" ne "0" %then %do; + proc transpose data=&inputparams out=&ds1; + id name; + var value; + run; + %end; + %else %do; + data &ds1;run; + %end; + + /* parse the input files - convert to sasjs params */ + %local webcount i var sasjs_tables; + %if %quote(&inputfiles) ne 0 %then %do; + %let webcount=%sysfunc(countw(&inputfiles)); + %put &=webcount; + %do i=1 %to &webcount; + %let var=%scan(&inputfiles,&i,%str( )); + %local webfref&i webname&i sasjs&i.data; + %let webref&i=%scan(&var,1,%str(:)); + %let webname&i=%scan(&var,2,%str(:)); + %put webref&i=&&webref&i; + %put webname&i=&&webname&i; + + %let sasjs_tables=&sasjs_tables &&webname&i; + data _null_; + infile &&webref&i lrecl=32767; + input; + if _n_=1 then call symputx("sasjs&i.data",_infile_); + else call symputx( + "sasjs&i.data",cats(symget("sasjs&i.data"),'0D0A'x,_infile_) + ); + putlog "&sysmacroname infile: " _infile_; + run; + data &ds1; + set &ds1; + length sasjs&i.data $32767 sasjs_tables $1000; + sasjs&i.data=symget("sasjs&i.data"); + sasjs_tables=symget("sasjs_tables"); + run; + %end; + %end; + %else %let webcount=0; + + data &ds1; + retain _program "&program"; + retain _contextname "&viyacontext"; + set &ds1; + putlog "&sysmacroname inputparams:"; + putlog (_all_)(=); + run; + + %mv_jobflow(inds=&ds1 + ,maxconcurrency=1 + ,outds=work.results + ,outref=&fref1 + ,mdebug=&mdebug + ) + /* show the log */ + data _null_; + infile &fref1; + input; + putlog _infile_; + run; + /* get the uri to fetch results */ + data _null_; + set work.results; + call symputx('uri',uri); + putlog "&sysmacroname: fetching results for " uri; + run; + /* fetch results from webout.json */ + %mv_getjobresult(uri=&uri, + result=&viyaresult, + outref=&outref, + outlib=&outlib, + mdebug=&mdebug + ) + +%end; +%else %if &platform=SASJS %then %do; + + %ms_testservice(&program + ,inputfiles=&inputfiles + ,inputdatasets=&inputdatasets + ,inputparams=&inputparams + ,debug=&debug + ,mdebug=&mdebug + ,outlib=&outlib + ,outref=&outref + ) + +%end; +%else %do; + %put %str(ERR)OR: Unrecognised platform: &platform; +%end; + +%if &mdebug=0 %then %do; + filename &fref1 clear; + %if &platform ne SASJS %then %do; + filename &fref2 clear; + filename &webref clear; + %end; +%end; +%else %do; + %put &sysmacroname exit vars:; + %put _local_; +%end; + +%mend mx_testservice;