1
0
mirror of https://github.com/sasjs/core.git synced 2026-01-11 11:00:04 +00:00

Compare commits

...

26 Commits

Author SHA1 Message Date
Allan Bowe
c6703e16e8 Merge pull request #285 from sasjs/mf_increment
feat: new mf_increment macro
2022-07-14 08:57:49 +01:00
munja
6587dce95b feat: new mf_increment macro 2022-07-13 23:57:02 +01:00
Allan Bowe
b60e6448b9 Merge pull request #284 from sasjs/allanbowe/dictionary-table-constraints-283
fix: avoid exceptions from dictionary.table_constraints.
2022-07-13 19:05:33 +01:00
Allan Bowe
46d9b58b32 fix: avoid exceptions from dictionary.table_constraints.
Closes #283
2022-07-13 18:01:52 +00:00
Allan Bowe
349cbabc94 Merge pull request #282 from sasjs/allanbowe/error-multiple-lengths-281
fix: prevent warning from `_label_` variable with different lengths
2022-07-12 23:29:47 +01:00
Allan Bowe
9de056a3fc fix: prevent warning from _label_ variable with different lengths
Closes #281
2022-07-12 22:18:01 +00:00
Allan Bowe
ad497b322f chore(tests): adding some extra test cases 2022-07-12 15:03:41 +00:00
Allan Bowe
7a6408ee44 Merge pull request #280 from sasjs/allanbowe/support-special-missings-279
fix: supporting special missings in BETWEEN and IN operators
2022-07-08 00:25:53 +01:00
Allan Bowe
336743f2b4 fix: applying logic to BETWEEN as well as IN 2022-07-07 23:24:24 +00:00
Allan Bowe
6e32eb3bd6 fix: supporting special missings in BETWEEN and IN operators
Impacts mp_filtercheck.sas.  Tests added.  Closes #279
2022-07-07 22:47:04 +00:00
Allan Bowe
b377b83442 Merge pull request #278 from sasjs/allanbowe/add-iftrue-parameter-277
fix: iftrue parameter for mp_binarycopy.  Closes #277
2022-07-07 11:29:25 +01:00
Allan Bowe
899b94bb6e fix: iftrue parameter for mp_binarycopy. Closes #277 2022-07-07 10:28:24 +00:00
Allan Bowe
d97efdff61 Merge pull request #276 from sasjs/allanbowe/syswarningtext-with-embedded-275
fix: escaping SYSWARNINGTEXT and SYSERRORTEXT for JSON response
2022-07-06 12:57:19 +01:00
Allan Bowe
1097afbcb8 fix: escaping SYSWARNINGTEXT and SYSERRORTEXT for JSON response
Closes #275
2022-07-06 11:55:15 +00:00
Allan Bowe
165b2d3568 Merge pull request #274 from sasjs/getpk
fix: enabling cross-compatibility of mp_getpk macro
2022-07-04 22:36:10 +01:00
Allan Bowe
44a80c8985 fix: enabling cross-compatibility of mp_getpk macro 2022-07-04 21:32:41 +00:00
Allan Bowe
6e32d9b743 Merge pull request #273 from sasjs/allanbowe/mp-jsonout-fails-in-meta-272
fix: setting length of label property in mp_jsonout
2022-07-04 13:27:02 +01:00
Allan Bowe
6b167e7a4c fix: longer label to allow for escapes 2022-07-04 12:26:19 +00:00
Allan Bowe
011672b1ed fix: setting length of label property in mp_jsonout 2022-07-04 12:24:53 +00:00
Allan Bowe
a7eb926810 Merge pull request #271 from sasjs/ms_getusers
fix: ensuring results when strict mode enabled in ms_getusers
2022-07-02 21:14:06 +01:00
Allan Bowe
cad7f13a0e fix: ensuring results when strict mode enabled in ms_getusers 2022-07-02 20:13:02 +00:00
Allan Bowe
65fcea817a Merge pull request #270 from sasjs/forcerelease
fix: forcing release for the previous fix
2022-07-01 00:17:11 +02:00
Allan Bowe
22fade13e7 fix: forcing release for the previous fix 2022-06-30 22:16:45 +00:00
Allan Bowe
7146310072 fix: missing ampersand 2022-06-30 22:06:27 +00:00
Allan Bowe
b7de1c25ec Merge pull request #269 from sasjs/jsonfix
fix: mX_webout macros in DEBUG mode had truncated json
2022-06-30 23:44:44 +02:00
Allan Bowe
f4c7f47ffe fix: mX_webout macros in DEBUG mode had truncated json
This was due to options obs=10 which affected new cross-encoding streaming technique
2022-06-30 21:41:10 +00:00
21 changed files with 383 additions and 150 deletions

231
all.sas
View File

@@ -198,6 +198,11 @@ options noquotelenmax;
%else %if "&SYSVLONG" < "9.04.01M3" %then 0; %else %if "&SYSVLONG" < "9.04.01M3" %then 0;
%else 1; %else 1;
%end; %end;
%else %if &feature=DBMS_MEMTYPE %then %do;
/* does dbms_memtype exist in dictionary.tables? */
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 0;
%else 1;
%end;
%else %if &feature=EXPORTXLS %then %do; %else %if &feature=EXPORTXLS %then %do;
/* is it possible to PROC EXPORT an excel file? */ /* is it possible to PROC EXPORT an excel file? */
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1; %if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1;
@@ -1593,6 +1598,35 @@ Usage:
&engine &engine
%mend mf_getxengine; %mend mf_getxengine;
/**
@file
@brief Increments a macro variable
@details Useful outside of do-loops - will increment a macro variable every
time it is called.
Example:
%let cnt=1;
%put We have run %mf_increment(cnt) lines;
%put Now we have run %mf_increment(cnt) lines;
%put There are %mf_increment(cnt) lines in total;
@param [in] MACRO_NAME the name of the macro variable to increment
@param [in] ITER= The amount to add or subtract to the macro
<h4> Related Files </h4>
@li mf_increment.test.sas
**/
%macro mf_increment(macro_name,incr=1);
/* iterate the value */
%let &macro_name=%eval(&&&macro_name+&incr);
/* return the value */
&&&macro_name
%mend mf_increment;
/** /**
@file mf_isblank.sas @file mf_isblank.sas
@brief Checks whether a macro variable is empty (blank) @brief Checks whether a macro variable is empty (blank)
@@ -2408,7 +2442,7 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
_PROGRAM=quote(trim(resolve(symget('_PROGRAM')))); _PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
syserrortext=quote(trim(symget('syserrortext'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ",""SYSERRORTEXT"" : " syserrortext; put ",""SYSERRORTEXT"" : " syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
@@ -2416,7 +2450,7 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(trim(symget('syswarningtext'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ",""SYSWARNINGTEXT"" : " syswarningtext; put ",""SYSWARNINGTEXT"" : " syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
put "}" ; put "}" ;
@@ -3500,6 +3534,7 @@ run;
@param [in] mode (CREATE) Valid values: @param [in] mode (CREATE) Valid values:
@li CREATE - Create the file (even if it already exists) @li CREATE - Create the file (even if it already exists)
@li APPEND - Append to the file (don't overwrite) @li APPEND - Append to the file (don't overwrite)
@param iftrue= (1=1) Supply a condition for which the macro should be executed
@returns nothing @returns nothing
@@ -3513,8 +3548,12 @@ run;
,inref=____in /* override default to use own filerefs */ ,inref=____in /* override default to use own filerefs */
,outref=____out /* override default to use own filerefs */ ,outref=____out /* override default to use own filerefs */
,mode=CREATE ,mode=CREATE
,iftrue=%str(1=1)
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local mod; %local mod;
%if not(%eval(%unquote(&iftrue))) %then %return;
%if &mode=APPEND %then %let mod=mod; %if &mode=APPEND %then %let mod=mod;
/* these IN and OUT filerefs can point to anything */ /* these IN and OUT filerefs can point to anything */
@@ -5873,7 +5912,8 @@ data &outds;
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32 /*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
OPERATOR_NM $10 RAW_VALUE $4000;*/ OPERATOR_NM $10 RAW_VALUE $4000;*/
set &inds; set &inds;
length reason_cd $4032 vtype $1 vnum dsid 8; length reason_cd $4032 vtype $1 vnum dsid 8 tmp $4000;
drop tmp;
/* quick check to ensure column exists */ /* quick check to ensure column exists */
if upcase(VARIABLE_NM) not in if upcase(VARIABLE_NM) not in
@@ -5949,18 +5989,32 @@ data &outds;
end; end;
/* special logic */ /* special logic */
if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',''); if OPERATOR_NM in ('IN','NOT IN','BETWEEN') then do;
else if OPERATOR_NM in ('IN','NOT IN') then do; if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',',');
if substr(raw_value,1,1) ne '(' else do;
or substr(cats(reverse(raw_value)),1,1) ne ')' if substr(raw_value,1,1) ne '('
then do; or substr(cats(reverse(raw_value)),1,1) ne ')'
REASON_CD='Missing start/end bracket in RAW_VALUE'; then do;
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; REASON_CD='Missing start/end bracket in RAW_VALUE';
call symputx('reason_cd',reason_cd,'l'); putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
call symputx('nobs',_n_,'l'); call symputx('reason_cd',reason_cd,'l');
output; call symputx('nobs',_n_,'l');
output;
end;
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
end;
/* we now have a comma seperated list of values */
if vtype='N' then do i=1 to countc(raw_value1, ',')+1;
tmp=scan(raw_value1,i,',');
if cats(tmp) ne '.' and input(tmp, ?? 8.) eq . then do;
REASON_CD='Non Numeric value provided';
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
end;
return;
end; end;
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
end; end;
else raw_value1=raw_value; else raw_value1=raw_value;
@@ -6640,8 +6694,11 @@ create table &outds as
/** /**
* We cannot apply this clause to the underlying dictionary table. See: * We cannot apply this clause to the underlying dictionary table. See:
* https://communities.sas.com/t5/SAS-Programming/Unexpected-Where-Clause-behaviour-in-dictionary-TABLE/m-p/771554#M244867 * https://communities.sas.com/t5/SAS-Programming/Unexpected-Where-Clause-behaviour-in-dictionary-TABLE/m-p/771554#M244867
* cannot use`where calculated libref="&lib"` either as it will STILL execute
* all the underlying constraint queries, causing exception errors in some
* cases: https://github.com/sasjs/core/issues/283
*/ */
where calculated libref="&lib" where a.TABLE_CATALOG="&lib"
%if "&ds" ne "" %then %do; %if "&ds" ne "" %then %do;
and upcase(a.TABLE_NAME)="&ds" and upcase(a.TABLE_NAME)="&ds"
and upcase(b.TABLE_NAME)="&ds" and upcase(b.TABLE_NAME)="&ds"
@@ -7676,6 +7733,7 @@ create table &outds (rename=(
@param [out] outds= (work.mp_getpk) The name of the output table to create. @param [out] outds= (work.mp_getpk) The name of the output table to create.
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_existfeature.sas
@li mf_getengine.sas @li mf_getengine.sas
@li mf_getschema.sas @li mf_getschema.sas
@li mp_dropmembers.sas @li mp_dropmembers.sas
@@ -7871,7 +7929,12 @@ create table work.&tabs1 as select
libname as libref libname as libref
,upcase(memname) as dsn ,upcase(memname) as dsn
,memtype ,memtype
%if %mf_existfeature(DBMS_MEMTYPE)=1 %then %do;
,dbms_memtype ,dbms_memtype
%end;
%else %do;
,'n/a' as dbms_memtype format=$32.
%end;
,typemem ,typemem
,memlabel ,memlabel
,nvar ,nvar
@@ -8605,7 +8668,7 @@ options
%mp_jsonout(OPEN,jref=tmp) %mp_jsonout(OPEN,jref=tmp)
%mp_jsonout(OBJ,class,jref=tmp) %mp_jsonout(OBJ,class,jref=tmp)
%mp_jsonout(OBJ,class,dslabel=class2,jref=tmp,showmeta=YES) %mp_jsonout(OBJ,class,dslabel=class2,jref=tmp,showmeta=Y)
%mp_jsonout(CLOSE,jref=tmp) %mp_jsonout(CLOSE,jref=tmp)
data _null_; data _null_;
@@ -8632,10 +8695,12 @@ options
@li DATASTEP (more reliable when data has non standard characters) @li DATASTEP (more reliable when data has non standard characters)
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
that should be converted to JSON
<h4> Related Macros <h4> <h4> Related Macros <h4>
@li mp_ds2fmtds.sas @li mp_ds2fmtds.sas
@@ -8649,10 +8714,12 @@ options
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y %macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y
,engine=DATASTEP ,engine=DATASTEP
,missing=NULL ,missing=NULL
,showmeta=NO ,showmeta=N
,maxobs=MAX
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local tempds colinfo fmtds i numcols; %local tempds colinfo fmtds i numcols stmt_obs;
%let numcols=0; %let numcols=0;
%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;);
%if &action=OPEN %then %do; %if &action=OPEN %then %do;
options nobomfile; options nobomfile;
@@ -8731,7 +8798,9 @@ options
%put &sysmacroname: Switching to DATASTEP engine; %put &sysmacroname: Switching to DATASTEP engine;
%goto datastep; %goto datastep;
%end; %end;
data &tempds;set &ds; data &tempds;
set &ds;
&stmt_obs;
%if &fmt=N %then format _numeric_ best32.;; %if &fmt=N %then format _numeric_ best32.;;
/* PRETTY is necessary to avoid line truncation in large files */ /* PRETTY is necessary to avoid line truncation in large files */
filename _sjs2 temp lrecl=131068 encoding='utf-8'; filename _sjs2 temp lrecl=131068 encoding='utf-8';
@@ -8806,6 +8875,7 @@ options
%else %do; %else %do;
set &ds; set &ds;
%end; %end;
&stmt_obs;
format _numeric_ bart.; format _numeric_ bart.;
%do i=1 %to &numcols; %do i=1 %to &numcols;
%if &&typelong&i=char or &fmt=Y %then %do; %if &&typelong&i=char or &fmt=Y %then %do;
@@ -8862,10 +8932,11 @@ options
proc sql; proc sql;
drop table &colinfo, &tempds; drop table &colinfo, &tempds;
%if &showmeta=YES %then %do; %if %substr(&showmeta,1,1)=Y %then %do;
filename _sjs4 temp lrecl=131068 encoding='utf-8'; filename _sjs4 temp lrecl=131068 encoding='utf-8';
data _null_; data _null_;
file _sjs4; file _sjs4;
length label $350;
put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{";
do i=1 to &numcols; do i=1 to &numcols;
name=quote(trim(symget(cats('name',i)))); name=quote(trim(symget(cats('name',i))));
@@ -11745,7 +11816,9 @@ run;
%else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE); %else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE);
data &ds4; data &ds4;
length &inds_keep $41 tgtvar_nm $32; length &inds_keep $41 tgtvar_nm $32 _label_ $256;
if _n_=1 then call missing(_label_);
drop _label_;
set &ds2 &ds3 indsname=&inds_auto; set &ds2 &ds3 indsname=&inds_auto;
tgtvar_nm=upcase(tgtvar_nm); tgtvar_nm=upcase(tgtvar_nm);
@@ -15060,10 +15133,12 @@ data _null_;
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y '; put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
put ' ,engine=DATASTEP '; put ' ,engine=DATASTEP ';
put ' ,missing=NULL '; put ' ,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put ' ,maxobs=MAX ';
put ')/*/STORE SOURCE*/; '; put ')/*/STORE SOURCE*/; ';
put '%local tempds colinfo fmtds i numcols; '; put '%local tempds colinfo fmtds i numcols stmt_obs; ';
put '%let numcols=0; '; put '%let numcols=0; ';
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
put ' '; put ' ';
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
@@ -15142,7 +15217,9 @@ data _null_;
put ' %put &sysmacroname: Switching to DATASTEP engine; '; put ' %put &sysmacroname: Switching to DATASTEP engine; ';
put ' %goto datastep; '; put ' %goto datastep; ';
put ' %end; '; put ' %end; ';
put ' data &tempds;set &ds; '; put ' data &tempds; ';
put ' set &ds; ';
put ' &stmt_obs; ';
put ' %if &fmt=N %then format _numeric_ best32.;; '; put ' %if &fmt=N %then format _numeric_ best32.;; ';
put ' /* PRETTY is necessary to avoid line truncation in large files */ '; put ' /* PRETTY is necessary to avoid line truncation in large files */ ';
put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
@@ -15217,6 +15294,7 @@ data _null_;
put ' %else %do; '; put ' %else %do; ';
put ' set &ds; '; put ' set &ds; ';
put ' %end; '; put ' %end; ';
put ' &stmt_obs; ';
put ' format _numeric_ bart.; '; put ' format _numeric_ bart.; ';
put ' %do i=1 %to &numcols; '; put ' %do i=1 %to &numcols; ';
put ' %if &&typelong&i=char or &fmt=Y %then %do; '; put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
@@ -15273,10 +15351,11 @@ data _null_;
put ' proc sql; '; put ' proc sql; ';
put ' drop table &colinfo, &tempds; '; put ' drop table &colinfo, &tempds; ';
put ' '; put ' ';
put ' %if &showmeta=YES %then %do; '; put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
put ' data _null_; '; put ' data _null_; ';
put ' file _sjs4; '; put ' file _sjs4; ';
put ' length label $350; ';
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; '; put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
put ' do i=1 to &numcols; '; put ' do i=1 to &numcols; ';
put ' name=quote(trim(symget(cats(''name'',i)))); '; put ' name=quote(trim(symget(cats(''name'',i)))); ';
@@ -15329,7 +15408,7 @@ data _null_;
put ' '; put ' ';
put '%mend mf_getuser; '; put '%mend mf_getuser; ';
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL '; put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put '); '; put '); ';
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug '; put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
put ' sasjs_tables; '; put ' sasjs_tables; ';
@@ -15404,7 +15483,6 @@ data _null_;
put ' filename _sjsref temp lrecl=131068; '; put ' filename _sjsref temp lrecl=131068; ';
put ' %if %str(&_debug) ge 131 %then %do; '; put ' %if %str(&_debug) ge 131 %then %do; ';
put ' /* if debug mode, send back first 10 records of each work table also */ '; put ' /* if debug mode, send back first 10 records of each work table also */ ';
put ' options obs=10; ';
put ' data;run;%let tempds=%scan(&syslast,2,.); '; put ' data;run;%let tempds=%scan(&syslast,2,.); ';
put ' ods output Members=&tempds; '; put ' ods output Members=&tempds; ';
put ' proc datasets library=WORK memtype=data; '; put ' proc datasets library=WORK memtype=data; ';
@@ -15428,7 +15506,7 @@ data _null_;
put ' put " ""&wt"" : {"; '; put ' put " ""&wt"" : {"; ';
put ' put ''"nlobs":'' nlobs; '; put ' put ''"nlobs":'' nlobs; ';
put ' put '',"nvars":'' nvars; '; put ' put '',"nvars":'' nvars; ';
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=YES) '; put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
put ' data _null_; file _sjsref mod encoding=''utf-8''; '; put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
put ' put "}"; '; put ' put "}"; ';
put ' %end; '; put ' %end; ';
@@ -15449,7 +15527,7 @@ data _null_;
put ' put '',"_PROGRAM" : '' _PROGRAM ; '; put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; '; put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); '; put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
put ' put '',"SYSERRORTEXT" : '' syserrortext; '; put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; '; put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
@@ -15457,7 +15535,7 @@ data _null_;
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); '; put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; '; put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; '; put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
put ' length memsize $32; '; put ' length memsize $32; ';
@@ -18878,7 +18956,7 @@ run;
@param [out] fref= (_webout) The fileref to which to write the JSON @param [out] fref= (_webout) The fileref to which to write the JSON
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@@ -18892,7 +18970,7 @@ run;
**/ **/
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL %macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
,showmeta=NO ,showmeta=N
); );
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug %global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
sasjs_tables; sasjs_tables;
@@ -18967,7 +19045,6 @@ run;
filename _sjsref temp lrecl=131068; filename _sjsref temp lrecl=131068;
%if %str(&_debug) ge 131 %then %do; %if %str(&_debug) ge 131 %then %do;
/* if debug mode, send back first 10 records of each work table also */ /* if debug mode, send back first 10 records of each work table also */
options obs=10;
data;run;%let tempds=%scan(&syslast,2,.); data;run;%let tempds=%scan(&syslast,2,.);
ods output Members=&tempds; ods output Members=&tempds;
proc datasets library=WORK memtype=data; proc datasets library=WORK memtype=data;
@@ -18991,7 +19068,7 @@ run;
put " ""&wt"" : {"; put " ""&wt"" : {";
put '"nlobs":' nlobs; put '"nlobs":' nlobs;
put ',"nvars":' nvars; put ',"nvars":' nvars;
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=YES) %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10)
data _null_; file _sjsref mod encoding='utf-8'; data _null_; file _sjsref mod encoding='utf-8';
put "}"; put "}";
%end; %end;
@@ -19012,7 +19089,7 @@ run;
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
put ",""SYSENCODING"" : ""&sysencoding"" "; put ",""SYSENCODING"" : ""&sysencoding"" ";
syserrortext=quote(cats(symget('SYSERRORTEXT'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ',"SYSERRORTEXT" : ' syserrortext; put ',"SYSERRORTEXT" : ' syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
@@ -19020,7 +19097,7 @@ run;
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(cats(symget('SYSWARNINGTEXT'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ',"SYSWARNINGTEXT" : ' syswarningtext; put ',"SYSWARNINGTEXT" : ' syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
length memsize $32; length memsize $32;
@@ -19858,10 +19935,12 @@ data _null_;
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y '; put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
put ' ,engine=DATASTEP '; put ' ,engine=DATASTEP ';
put ' ,missing=NULL '; put ' ,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put ' ,maxobs=MAX ';
put ')/*/STORE SOURCE*/; '; put ')/*/STORE SOURCE*/; ';
put '%local tempds colinfo fmtds i numcols; '; put '%local tempds colinfo fmtds i numcols stmt_obs; ';
put '%let numcols=0; '; put '%let numcols=0; ';
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
put ' '; put ' ';
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
@@ -19940,7 +20019,9 @@ data _null_;
put ' %put &sysmacroname: Switching to DATASTEP engine; '; put ' %put &sysmacroname: Switching to DATASTEP engine; ';
put ' %goto datastep; '; put ' %goto datastep; ';
put ' %end; '; put ' %end; ';
put ' data &tempds;set &ds; '; put ' data &tempds; ';
put ' set &ds; ';
put ' &stmt_obs; ';
put ' %if &fmt=N %then format _numeric_ best32.;; '; put ' %if &fmt=N %then format _numeric_ best32.;; ';
put ' /* PRETTY is necessary to avoid line truncation in large files */ '; put ' /* PRETTY is necessary to avoid line truncation in large files */ ';
put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
@@ -20015,6 +20096,7 @@ data _null_;
put ' %else %do; '; put ' %else %do; ';
put ' set &ds; '; put ' set &ds; ';
put ' %end; '; put ' %end; ';
put ' &stmt_obs; ';
put ' format _numeric_ bart.; '; put ' format _numeric_ bart.; ';
put ' %do i=1 %to &numcols; '; put ' %do i=1 %to &numcols; ';
put ' %if &&typelong&i=char or &fmt=Y %then %do; '; put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
@@ -20071,10 +20153,11 @@ data _null_;
put ' proc sql; '; put ' proc sql; ';
put ' drop table &colinfo, &tempds; '; put ' drop table &colinfo, &tempds; ';
put ' '; put ' ';
put ' %if &showmeta=YES %then %do; '; put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
put ' data _null_; '; put ' data _null_; ';
put ' file _sjs4; '; put ' file _sjs4; ';
put ' length label $350; ';
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; '; put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
put ' do i=1 to &numcols; '; put ' do i=1 to &numcols; ';
put ' name=quote(trim(symget(cats(''name'',i)))); '; put ' name=quote(trim(symget(cats(''name'',i)))); ';
@@ -20128,7 +20211,7 @@ data _null_;
put '%mend mf_getuser; '; put '%mend mf_getuser; ';
put ' '; put ' ';
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL '; put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put '); '; put '); ';
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug '; put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
put ' sasjs_tables; '; put ' sasjs_tables; ';
@@ -20193,7 +20276,6 @@ data _null_;
put '%else %if &action=CLOSE %then %do; '; put '%else %if &action=CLOSE %then %do; ';
put ' %if %str(&_debug) ge 131 %then %do; '; put ' %if %str(&_debug) ge 131 %then %do; ';
put ' /* if debug mode, send back first 10 records of each work table also */ '; put ' /* if debug mode, send back first 10 records of each work table also */ ';
put ' options obs=10; ';
put ' data;run;%let tempds=%scan(&syslast,2,.); '; put ' data;run;%let tempds=%scan(&syslast,2,.); ';
put ' ods output Members=&tempds; '; put ' ods output Members=&tempds; ';
put ' proc datasets library=WORK memtype=data; '; put ' proc datasets library=WORK memtype=data; ';
@@ -20218,7 +20300,7 @@ data _null_;
put ' put " ""&wt"" : {"; '; put ' put " ""&wt"" : {"; ';
put ' put ''"nlobs":'' nlobs; '; put ' put ''"nlobs":'' nlobs; ';
put ' put '',"nvars":'' nvars; '; put ' put '',"nvars":'' nvars; ';
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) '; put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; '; put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
put ' put "}"; '; put ' put "}"; ';
put ' %end; '; put ' %end; ';
@@ -20235,7 +20317,7 @@ data _null_;
put ' put '',"_PROGRAM" : '' _PROGRAM ; '; put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; '; put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); '; put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
put ' put '',"SYSERRORTEXT" : '' syserrortext; '; put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
put ' SYSHOSTINFOLONG=quote(trim(symget(''SYSHOSTINFOLONG''))); '; put ' SYSHOSTINFOLONG=quote(trim(symget(''SYSHOSTINFOLONG''))); ';
put ' put '',"SYSHOSTINFOLONG" : '' SYSHOSTINFOLONG; '; put ' put '',"SYSHOSTINFOLONG" : '' SYSHOSTINFOLONG; ';
@@ -20251,7 +20333,7 @@ data _null_;
put ' put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; '; put ' put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); '; put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; '; put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; '; put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
put ' length autoexec $512; '; put ' length autoexec $512; ';
@@ -20689,14 +20771,16 @@ libname &libref JSON fileref=&fref1;
%if "&group"="0" and "&gid"="0" %then %do; %if "&group"="0" and "&gid"="0" %then %do;
data &outds; data &outds;
length DISPLAYNAME $60 USERNAME:$30 ID 8; length DISPLAYNAME $60 USERNAME:$30 ID 8;
set &libref..root; if nobs=0 then call missing(of _all_);
set &libref..root nobs=nobs;
drop ordinal_root; drop ordinal_root;
run; run;
%end; %end;
%else %do; %else %do;
data &outds; data &outds;
length DISPLAYNAME $60 USERNAME:$30 ID 8; length DISPLAYNAME $60 USERNAME:$30 ID 8;
set &libref..users; if nobs=0 then call missing(of _all_);
set &libref..users nobs=nobs;
drop ordinal_root ordinal_users; drop ordinal_root ordinal_users;
run; run;
%end; %end;
@@ -21098,7 +21182,7 @@ run;
@param [out] fref= (_webout) The fileref to which to write the JSON @param [out] fref= (_webout) The fileref to which to write the JSON
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@@ -21118,7 +21202,7 @@ run;
**/ **/
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL %macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
,showmeta=NO ,showmeta=N
); );
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug %global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
sasjs_tables; sasjs_tables;
@@ -21183,7 +21267,6 @@ run;
%else %if &action=CLOSE %then %do; %else %if &action=CLOSE %then %do;
%if %str(&_debug) ge 131 %then %do; %if %str(&_debug) ge 131 %then %do;
/* if debug mode, send back first 10 records of each work table also */ /* if debug mode, send back first 10 records of each work table also */
options obs=10;
data;run;%let tempds=%scan(&syslast,2,.); data;run;%let tempds=%scan(&syslast,2,.);
ods output Members=&tempds; ods output Members=&tempds;
proc datasets library=WORK memtype=data; proc datasets library=WORK memtype=data;
@@ -21208,7 +21291,7 @@ run;
put " ""&wt"" : {"; put " ""&wt"" : {";
put '"nlobs":' nlobs; put '"nlobs":' nlobs;
put ',"nvars":' nvars; put ',"nvars":' nvars;
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
data _null_; file &fref mod encoding='utf-8' termstr=lf; data _null_; file &fref mod encoding='utf-8' termstr=lf;
put "}"; put "}";
%end; %end;
@@ -21225,7 +21308,7 @@ run;
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
put ",""SYSENCODING"" : ""&sysencoding"" "; put ",""SYSENCODING"" : ""&sysencoding"" ";
syserrortext=quote(cats(symget('SYSERRORTEXT'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ',"SYSERRORTEXT" : ' syserrortext; put ',"SYSERRORTEXT" : ' syserrortext;
SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG'))); SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG')));
put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG; put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG;
@@ -21241,7 +21324,7 @@ run;
put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(cats(symget('SYSWARNINGTEXT'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ',"SYSWARNINGTEXT" : ' syswarningtext; put ',"SYSWARNINGTEXT" : ' syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
length autoexec $512; length autoexec $512;
@@ -22233,10 +22316,12 @@ data _null_;
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y '; put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
put ' ,engine=DATASTEP '; put ' ,engine=DATASTEP ';
put ' ,missing=NULL '; put ' ,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put ' ,maxobs=MAX ';
put ')/*/STORE SOURCE*/; '; put ')/*/STORE SOURCE*/; ';
put '%local tempds colinfo fmtds i numcols; '; put '%local tempds colinfo fmtds i numcols stmt_obs; ';
put '%let numcols=0; '; put '%let numcols=0; ';
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
put ' '; put ' ';
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
@@ -22315,7 +22400,9 @@ data _null_;
put ' %put &sysmacroname: Switching to DATASTEP engine; '; put ' %put &sysmacroname: Switching to DATASTEP engine; ';
put ' %goto datastep; '; put ' %goto datastep; ';
put ' %end; '; put ' %end; ';
put ' data &tempds;set &ds; '; put ' data &tempds; ';
put ' set &ds; ';
put ' &stmt_obs; ';
put ' %if &fmt=N %then format _numeric_ best32.;; '; put ' %if &fmt=N %then format _numeric_ best32.;; ';
put ' /* PRETTY is necessary to avoid line truncation in large files */ '; put ' /* PRETTY is necessary to avoid line truncation in large files */ ';
put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
@@ -22390,6 +22477,7 @@ data _null_;
put ' %else %do; '; put ' %else %do; ';
put ' set &ds; '; put ' set &ds; ';
put ' %end; '; put ' %end; ';
put ' &stmt_obs; ';
put ' format _numeric_ bart.; '; put ' format _numeric_ bart.; ';
put ' %do i=1 %to &numcols; '; put ' %do i=1 %to &numcols; ';
put ' %if &&typelong&i=char or &fmt=Y %then %do; '; put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
@@ -22446,10 +22534,11 @@ data _null_;
put ' proc sql; '; put ' proc sql; ';
put ' drop table &colinfo, &tempds; '; put ' drop table &colinfo, &tempds; ';
put ' '; put ' ';
put ' %if &showmeta=YES %then %do; '; put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
put ' data _null_; '; put ' data _null_; ';
put ' file _sjs4; '; put ' file _sjs4; ';
put ' length label $350; ';
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; '; put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
put ' do i=1 to &numcols; '; put ' do i=1 to &numcols; ';
put ' name=quote(trim(symget(cats(''name'',i)))); '; put ' name=quote(trim(symget(cats(''name'',i)))); ';
@@ -22502,7 +22591,7 @@ data _null_;
put ' '; put ' ';
put '%mend mf_getuser; '; put '%mend mf_getuser; ';
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL '; put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put '); '; put '); ';
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name '; put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
put ' sasjs_tables SYS_JES_JOB_URI; '; put ' sasjs_tables SYS_JES_JOB_URI; ';
@@ -22594,8 +22683,7 @@ data _null_;
put ' '; put ' ';
put ' /* setup temp ref */ '; put ' /* setup temp ref */ ';
put ' %if %upcase(&fref) ne _WEBOUT %then %do; '; put ' %if %upcase(&fref) ne _WEBOUT %then %do; ';
put ' filename &fref temp lrecl=999999 permission=''A::u::rwx,A::g::rw-,A::o::---'' '; put ' filename &fref temp lrecl=999999 permission=''A::u::rwx,A::g::rw-,A::o::---''; ';
put ' mod; ';
put ' %end; '; put ' %end; ';
put ' '; put ' ';
put ' /* setup json */ '; put ' /* setup json */ ';
@@ -22612,7 +22700,6 @@ data _null_;
put '%else %if &action=CLOSE %then %do; '; put '%else %if &action=CLOSE %then %do; ';
put ' %if %str(&_debug) ge 131 %then %do; '; put ' %if %str(&_debug) ge 131 %then %do; ';
put ' /* send back first 10 records of each work table for debugging */ '; put ' /* send back first 10 records of each work table for debugging */ ';
put ' options obs=10; ';
put ' data;run;%let tempds=%scan(&syslast,2,.); '; put ' data;run;%let tempds=%scan(&syslast,2,.); ';
put ' ods output Members=&tempds; '; put ' ods output Members=&tempds; ';
put ' proc datasets library=WORK memtype=data; '; put ' proc datasets library=WORK memtype=data; ';
@@ -22635,7 +22722,7 @@ data _null_;
put ' put " ""&wt"" : {"; '; put ' put " ""&wt"" : {"; ';
put ' put ''"nlobs":'' nlobs; '; put ' put ''"nlobs":'' nlobs; ';
put ' put '',"nvars":'' nvars; '; put ' put '',"nvars":'' nvars; ';
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) '; put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
put ' data _null_; file &fref mod;put "}"; '; put ' data _null_; file &fref mod;put "}"; ';
put ' %end; '; put ' %end; ';
put ' data _null_; file &fref mod;put "}";run; '; put ' data _null_; file &fref mod;put "}";run; ';
@@ -22652,14 +22739,14 @@ data _null_;
put ' put ",""_DEBUG"" : ""&_debug"" "; '; put ' put ",""_DEBUG"" : ""&_debug"" "; ';
put ' put '',"_PROGRAM" : '' _PROGRAM ; '; put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); '; put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
put ' put '',"SYSERRORTEXT" : '' syserrortext; '; put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; '; put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); '; put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; '; put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; '; put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
put ' length memsize $32; '; put ' length memsize $32; ';
@@ -26278,7 +26365,7 @@ filename &fref1 clear;
@param [in] stream=(Y) Change to N if not streaming to _webout @param [in] stream=(Y) Change to N if not streaming to _webout
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@@ -26292,7 +26379,7 @@ filename &fref1 clear;
**/ **/
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL %macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL
,showmeta=NO ,showmeta=N
); );
%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;
@@ -26384,8 +26471,7 @@ filename &fref1 clear;
/* setup temp ref */ /* setup temp ref */
%if %upcase(&fref) ne _WEBOUT %then %do; %if %upcase(&fref) ne _WEBOUT %then %do;
filename &fref temp lrecl=999999 permission='A::u::rwx,A::g::rw-,A::o::---' filename &fref temp lrecl=999999 permission='A::u::rwx,A::g::rw-,A::o::---';
mod;
%end; %end;
/* setup json */ /* setup json */
@@ -26402,7 +26488,6 @@ filename &fref1 clear;
%else %if &action=CLOSE %then %do; %else %if &action=CLOSE %then %do;
%if %str(&_debug) ge 131 %then %do; %if %str(&_debug) ge 131 %then %do;
/* send back first 10 records of each work table for debugging */ /* send back first 10 records of each work table for debugging */
options obs=10;
data;run;%let tempds=%scan(&syslast,2,.); data;run;%let tempds=%scan(&syslast,2,.);
ods output Members=&tempds; ods output Members=&tempds;
proc datasets library=WORK memtype=data; proc datasets library=WORK memtype=data;
@@ -26425,7 +26510,7 @@ filename &fref1 clear;
put " ""&wt"" : {"; put " ""&wt"" : {";
put '"nlobs":' nlobs; put '"nlobs":' nlobs;
put ',"nvars":' nvars; put ',"nvars":' nvars;
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
data _null_; file &fref mod;put "}"; data _null_; file &fref mod;put "}";
%end; %end;
data _null_; file &fref mod;put "}";run; data _null_; file &fref mod;put "}";run;
@@ -26442,14 +26527,14 @@ filename &fref1 clear;
put ",""_DEBUG"" : ""&_debug"" "; put ",""_DEBUG"" : ""&_debug"" ";
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
syserrortext=quote(cats(symget('SYSERRORTEXT'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ',"SYSERRORTEXT" : ' syserrortext; put ',"SYSERRORTEXT" : ' syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSSCPL"" : ""&sysscpl"" "; put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(cats(symget('SYSWARNINGTEXT'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ',"SYSWARNINGTEXT" : ' syswarningtext; put ',"SYSWARNINGTEXT" : ' syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
length memsize $32; length memsize $32;

View File

@@ -40,6 +40,11 @@
%else %if "&SYSVLONG" < "9.04.01M3" %then 0; %else %if "&SYSVLONG" < "9.04.01M3" %then 0;
%else 1; %else 1;
%end; %end;
%else %if &feature=DBMS_MEMTYPE %then %do;
/* does dbms_memtype exist in dictionary.tables? */
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 0;
%else 1;
%end;
%else %if &feature=EXPORTXLS %then %do; %else %if &feature=EXPORTXLS %then %do;
/* is it possible to PROC EXPORT an excel file? */ /* is it possible to PROC EXPORT an excel file? */
%if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1; %if "%substr(&sysver,1,1)"="4" or "%substr(&sysver,1,1)"="5" %then 1;

29
base/mf_increment.sas Normal file
View File

@@ -0,0 +1,29 @@
/**
@file
@brief Increments a macro variable
@details Useful outside of do-loops - will increment a macro variable every
time it is called.
Example:
%let cnt=1;
%put We have run %mf_increment(cnt) lines;
%put Now we have run %mf_increment(cnt) lines;
%put There are %mf_increment(cnt) lines in total;
@param [in] MACRO_NAME the name of the macro variable to increment
@param [in] ITER= The amount to add or subtract to the macro
<h4> Related Files </h4>
@li mf_increment.test.sas
**/
%macro mf_increment(macro_name,incr=1);
/* iterate the value */
%let &macro_name=%eval(&&&macro_name+&incr);
/* return the value */
&&&macro_name
%mend mf_increment;

View File

@@ -225,7 +225,7 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
_PROGRAM=quote(trim(resolve(symget('_PROGRAM')))); _PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
syserrortext=quote(trim(symget('syserrortext'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ",""SYSERRORTEXT"" : " syserrortext; put ",""SYSERRORTEXT"" : " syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
@@ -233,7 +233,7 @@ and %superq(SYSPROCESSNAME) ne %str(Compute Server)
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(trim(symget('syswarningtext'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ",""SYSWARNINGTEXT"" : " syswarningtext; put ",""SYSWARNINGTEXT"" : " syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
put "}" ; put "}" ;

View File

@@ -31,6 +31,7 @@
@param [in] mode (CREATE) Valid values: @param [in] mode (CREATE) Valid values:
@li CREATE - Create the file (even if it already exists) @li CREATE - Create the file (even if it already exists)
@li APPEND - Append to the file (don't overwrite) @li APPEND - Append to the file (don't overwrite)
@param iftrue= (1=1) Supply a condition for which the macro should be executed
@returns nothing @returns nothing
@@ -44,8 +45,12 @@
,inref=____in /* override default to use own filerefs */ ,inref=____in /* override default to use own filerefs */
,outref=____out /* override default to use own filerefs */ ,outref=____out /* override default to use own filerefs */
,mode=CREATE ,mode=CREATE
,iftrue=%str(1=1)
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local mod; %local mod;
%if not(%eval(%unquote(&iftrue))) %then %return;
%if &mode=APPEND %then %let mod=mod; %if &mode=APPEND %then %let mod=mod;
/* these IN and OUT filerefs can point to anything */ /* these IN and OUT filerefs can point to anything */

View File

@@ -92,7 +92,8 @@ data &outds;
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32 /*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
OPERATOR_NM $10 RAW_VALUE $4000;*/ OPERATOR_NM $10 RAW_VALUE $4000;*/
set &inds; set &inds;
length reason_cd $4032 vtype $1 vnum dsid 8; length reason_cd $4032 vtype $1 vnum dsid 8 tmp $4000;
drop tmp;
/* quick check to ensure column exists */ /* quick check to ensure column exists */
if upcase(VARIABLE_NM) not in if upcase(VARIABLE_NM) not in
@@ -168,18 +169,32 @@ data &outds;
end; end;
/* special logic */ /* special logic */
if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',''); if OPERATOR_NM in ('IN','NOT IN','BETWEEN') then do;
else if OPERATOR_NM in ('IN','NOT IN') then do; if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',',');
if substr(raw_value,1,1) ne '(' else do;
or substr(cats(reverse(raw_value)),1,1) ne ')' if substr(raw_value,1,1) ne '('
then do; or substr(cats(reverse(raw_value)),1,1) ne ')'
REASON_CD='Missing start/end bracket in RAW_VALUE'; then do;
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; REASON_CD='Missing start/end bracket in RAW_VALUE';
call symputx('reason_cd',reason_cd,'l'); putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
call symputx('nobs',_n_,'l'); call symputx('reason_cd',reason_cd,'l');
output; call symputx('nobs',_n_,'l');
output;
end;
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
end;
/* we now have a comma seperated list of values */
if vtype='N' then do i=1 to countc(raw_value1, ',')+1;
tmp=scan(raw_value1,i,',');
if cats(tmp) ne '.' and input(tmp, ?? 8.) eq . then do;
REASON_CD='Non Numeric value provided';
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
call symputx('reason_cd',reason_cd,'l');
call symputx('nobs',_n_,'l');
output;
end;
return;
end; end;
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
end; end;
else raw_value1=raw_value; else raw_value1=raw_value;

View File

@@ -94,8 +94,11 @@ create table &outds as
/** /**
* We cannot apply this clause to the underlying dictionary table. See: * We cannot apply this clause to the underlying dictionary table. See:
* https://communities.sas.com/t5/SAS-Programming/Unexpected-Where-Clause-behaviour-in-dictionary-TABLE/m-p/771554#M244867 * https://communities.sas.com/t5/SAS-Programming/Unexpected-Where-Clause-behaviour-in-dictionary-TABLE/m-p/771554#M244867
* cannot use`where calculated libref="&lib"` either as it will STILL execute
* all the underlying constraint queries, causing exception errors in some
* cases: https://github.com/sasjs/core/issues/283
*/ */
where calculated libref="&lib" where a.TABLE_CATALOG="&lib"
%if "&ds" ne "" %then %do; %if "&ds" ne "" %then %do;
and upcase(a.TABLE_NAME)="&ds" and upcase(a.TABLE_NAME)="&ds"
and upcase(b.TABLE_NAME)="&ds" and upcase(b.TABLE_NAME)="&ds"

View File

@@ -34,6 +34,7 @@
@param [out] outds= (work.mp_getpk) The name of the output table to create. @param [out] outds= (work.mp_getpk) The name of the output table to create.
<h4> SAS Macros </h4> <h4> SAS Macros </h4>
@li mf_existfeature.sas
@li mf_getengine.sas @li mf_getengine.sas
@li mf_getschema.sas @li mf_getschema.sas
@li mp_dropmembers.sas @li mp_dropmembers.sas
@@ -229,7 +230,12 @@ create table work.&tabs1 as select
libname as libref libname as libref
,upcase(memname) as dsn ,upcase(memname) as dsn
,memtype ,memtype
%if %mf_existfeature(DBMS_MEMTYPE)=1 %then %do;
,dbms_memtype ,dbms_memtype
%end;
%else %do;
,'n/a' as dbms_memtype format=$32.
%end;
,typemem ,typemem
,memlabel ,memlabel
,nvar ,nvar

View File

@@ -28,7 +28,7 @@
%mp_jsonout(OPEN,jref=tmp) %mp_jsonout(OPEN,jref=tmp)
%mp_jsonout(OBJ,class,jref=tmp) %mp_jsonout(OBJ,class,jref=tmp)
%mp_jsonout(OBJ,class,dslabel=class2,jref=tmp,showmeta=YES) %mp_jsonout(OBJ,class,dslabel=class2,jref=tmp,showmeta=Y)
%mp_jsonout(CLOSE,jref=tmp) %mp_jsonout(CLOSE,jref=tmp)
data _null_; data _null_;
@@ -55,10 +55,12 @@
@li DATASTEP (more reliable when data has non standard characters) @li DATASTEP (more reliable when data has non standard characters)
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@param [in] maxobs= (MAX) Provide an integer to limit the number of input rows
that should be converted to JSON
<h4> Related Macros <h4> <h4> Related Macros <h4>
@li mp_ds2fmtds.sas @li mp_ds2fmtds.sas
@@ -72,10 +74,12 @@
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y %macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y
,engine=DATASTEP ,engine=DATASTEP
,missing=NULL ,missing=NULL
,showmeta=NO ,showmeta=N
,maxobs=MAX
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local tempds colinfo fmtds i numcols; %local tempds colinfo fmtds i numcols stmt_obs;
%let numcols=0; %let numcols=0;
%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;);
%if &action=OPEN %then %do; %if &action=OPEN %then %do;
options nobomfile; options nobomfile;
@@ -154,7 +158,9 @@
%put &sysmacroname: Switching to DATASTEP engine; %put &sysmacroname: Switching to DATASTEP engine;
%goto datastep; %goto datastep;
%end; %end;
data &tempds;set &ds; data &tempds;
set &ds;
&stmt_obs;
%if &fmt=N %then format _numeric_ best32.;; %if &fmt=N %then format _numeric_ best32.;;
/* PRETTY is necessary to avoid line truncation in large files */ /* PRETTY is necessary to avoid line truncation in large files */
filename _sjs2 temp lrecl=131068 encoding='utf-8'; filename _sjs2 temp lrecl=131068 encoding='utf-8';
@@ -229,6 +235,7 @@
%else %do; %else %do;
set &ds; set &ds;
%end; %end;
&stmt_obs;
format _numeric_ bart.; format _numeric_ bart.;
%do i=1 %to &numcols; %do i=1 %to &numcols;
%if &&typelong&i=char or &fmt=Y %then %do; %if &&typelong&i=char or &fmt=Y %then %do;
@@ -285,10 +292,11 @@
proc sql; proc sql;
drop table &colinfo, &tempds; drop table &colinfo, &tempds;
%if &showmeta=YES %then %do; %if %substr(&showmeta,1,1)=Y %then %do;
filename _sjs4 temp lrecl=131068 encoding='utf-8'; filename _sjs4 temp lrecl=131068 encoding='utf-8';
data _null_; data _null_;
file _sjs4; file _sjs4;
length label $350;
put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{";
do i=1 to &numcols; do i=1 to &numcols;
name=quote(trim(symget(cats('name',i)))); name=quote(trim(symget(cats('name',i))));

View File

@@ -154,7 +154,9 @@ run;
%else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE); %else %let vlist=%mf_getvarlist(&libds,dlm=%str(,),quote=DOUBLE);
data &ds4; data &ds4;
length &inds_keep $41 tgtvar_nm $32; length &inds_keep $41 tgtvar_nm $32 _label_ $256;
if _n_=1 then call missing(_label_);
drop _label_;
set &ds2 &ds3 indsname=&inds_auto; set &ds2 &ds3 indsname=&inds_auto;
tgtvar_nm=upcase(tgtvar_nm); tgtvar_nm=upcase(tgtvar_nm);

View File

@@ -97,10 +97,12 @@ data _null_;
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y '; put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
put ' ,engine=DATASTEP '; put ' ,engine=DATASTEP ';
put ' ,missing=NULL '; put ' ,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put ' ,maxobs=MAX ';
put ')/*/STORE SOURCE*/; '; put ')/*/STORE SOURCE*/; ';
put '%local tempds colinfo fmtds i numcols; '; put '%local tempds colinfo fmtds i numcols stmt_obs; ';
put '%let numcols=0; '; put '%let numcols=0; ';
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
put ' '; put ' ';
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
@@ -179,7 +181,9 @@ data _null_;
put ' %put &sysmacroname: Switching to DATASTEP engine; '; put ' %put &sysmacroname: Switching to DATASTEP engine; ';
put ' %goto datastep; '; put ' %goto datastep; ';
put ' %end; '; put ' %end; ';
put ' data &tempds;set &ds; '; put ' data &tempds; ';
put ' set &ds; ';
put ' &stmt_obs; ';
put ' %if &fmt=N %then format _numeric_ best32.;; '; put ' %if &fmt=N %then format _numeric_ best32.;; ';
put ' /* PRETTY is necessary to avoid line truncation in large files */ '; put ' /* PRETTY is necessary to avoid line truncation in large files */ ';
put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
@@ -254,6 +258,7 @@ data _null_;
put ' %else %do; '; put ' %else %do; ';
put ' set &ds; '; put ' set &ds; ';
put ' %end; '; put ' %end; ';
put ' &stmt_obs; ';
put ' format _numeric_ bart.; '; put ' format _numeric_ bart.; ';
put ' %do i=1 %to &numcols; '; put ' %do i=1 %to &numcols; ';
put ' %if &&typelong&i=char or &fmt=Y %then %do; '; put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
@@ -310,10 +315,11 @@ data _null_;
put ' proc sql; '; put ' proc sql; ';
put ' drop table &colinfo, &tempds; '; put ' drop table &colinfo, &tempds; ';
put ' '; put ' ';
put ' %if &showmeta=YES %then %do; '; put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
put ' data _null_; '; put ' data _null_; ';
put ' file _sjs4; '; put ' file _sjs4; ';
put ' length label $350; ';
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; '; put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
put ' do i=1 to &numcols; '; put ' do i=1 to &numcols; ';
put ' name=quote(trim(symget(cats(''name'',i)))); '; put ' name=quote(trim(symget(cats(''name'',i)))); ';
@@ -366,7 +372,7 @@ data _null_;
put ' '; put ' ';
put '%mend mf_getuser; '; put '%mend mf_getuser; ';
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL '; put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put '); '; put '); ';
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug '; put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
put ' sasjs_tables; '; put ' sasjs_tables; ';
@@ -441,7 +447,6 @@ data _null_;
put ' filename _sjsref temp lrecl=131068; '; put ' filename _sjsref temp lrecl=131068; ';
put ' %if %str(&_debug) ge 131 %then %do; '; put ' %if %str(&_debug) ge 131 %then %do; ';
put ' /* if debug mode, send back first 10 records of each work table also */ '; put ' /* if debug mode, send back first 10 records of each work table also */ ';
put ' options obs=10; ';
put ' data;run;%let tempds=%scan(&syslast,2,.); '; put ' data;run;%let tempds=%scan(&syslast,2,.); ';
put ' ods output Members=&tempds; '; put ' ods output Members=&tempds; ';
put ' proc datasets library=WORK memtype=data; '; put ' proc datasets library=WORK memtype=data; ';
@@ -465,7 +470,7 @@ data _null_;
put ' put " ""&wt"" : {"; '; put ' put " ""&wt"" : {"; ';
put ' put ''"nlobs":'' nlobs; '; put ' put ''"nlobs":'' nlobs; ';
put ' put '',"nvars":'' nvars; '; put ' put '',"nvars":'' nvars; ';
put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=YES) '; put ' %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
put ' data _null_; file _sjsref mod encoding=''utf-8''; '; put ' data _null_; file _sjsref mod encoding=''utf-8''; ';
put ' put "}"; '; put ' put "}"; ';
put ' %end; '; put ' %end; ';
@@ -486,7 +491,7 @@ data _null_;
put ' put '',"_PROGRAM" : '' _PROGRAM ; '; put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; '; put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); '; put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
put ' put '',"SYSERRORTEXT" : '' syserrortext; '; put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; '; put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
@@ -494,7 +499,7 @@ data _null_;
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); '; put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; '; put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; '; put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
put ' length memsize $32; '; put ' length memsize $32; ';

View File

@@ -30,7 +30,7 @@
@param [out] fref= (_webout) The fileref to which to write the JSON @param [out] fref= (_webout) The fileref to which to write the JSON
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@@ -44,7 +44,7 @@
**/ **/
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL %macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
,showmeta=NO ,showmeta=N
); );
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug %global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
sasjs_tables; sasjs_tables;
@@ -119,7 +119,6 @@
filename _sjsref temp lrecl=131068; filename _sjsref temp lrecl=131068;
%if %str(&_debug) ge 131 %then %do; %if %str(&_debug) ge 131 %then %do;
/* if debug mode, send back first 10 records of each work table also */ /* if debug mode, send back first 10 records of each work table also */
options obs=10;
data;run;%let tempds=%scan(&syslast,2,.); data;run;%let tempds=%scan(&syslast,2,.);
ods output Members=&tempds; ods output Members=&tempds;
proc datasets library=WORK memtype=data; proc datasets library=WORK memtype=data;
@@ -143,7 +142,7 @@
put " ""&wt"" : {"; put " ""&wt"" : {";
put '"nlobs":' nlobs; put '"nlobs":' nlobs;
put ',"nvars":' nvars; put ',"nvars":' nvars;
%mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=YES) %mp_jsonout(OBJ,&wt,jref=_sjsref,dslabel=first10rows,showmeta=Y,maxobs=10)
data _null_; file _sjsref mod encoding='utf-8'; data _null_; file _sjsref mod encoding='utf-8';
put "}"; put "}";
%end; %end;
@@ -164,7 +163,7 @@
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
put ",""SYSENCODING"" : ""&sysencoding"" "; put ",""SYSENCODING"" : ""&sysencoding"" ";
syserrortext=quote(cats(symget('SYSERRORTEXT'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ',"SYSERRORTEXT" : ' syserrortext; put ',"SYSERRORTEXT" : ' syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSJOBID"" : ""&sysjobid"" "; put ",""SYSJOBID"" : ""&sysjobid"" ";
@@ -172,7 +171,7 @@
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(cats(symget('SYSWARNINGTEXT'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ',"SYSWARNINGTEXT" : ' syswarningtext; put ',"SYSWARNINGTEXT" : ' syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
length memsize $32; length memsize $32;

View File

@@ -67,7 +67,7 @@
}, },
{ {
"name": "server", "name": "server",
"serverUrl": "", "serverUrl": "https://sas.4gl.io",
"serverType": "SASJS", "serverType": "SASJS",
"httpsAgentOptions": { "httpsAgentOptions": {
"allowInsecureRequests": false "allowInsecureRequests": false
@@ -107,4 +107,4 @@
"contextName": "SAS Job Execution compute context" "contextName": "SAS Job Execution compute context"
} }
] ]
} }

View File

@@ -98,10 +98,12 @@ data _null_;
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y '; put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
put ' ,engine=DATASTEP '; put ' ,engine=DATASTEP ';
put ' ,missing=NULL '; put ' ,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put ' ,maxobs=MAX ';
put ')/*/STORE SOURCE*/; '; put ')/*/STORE SOURCE*/; ';
put '%local tempds colinfo fmtds i numcols; '; put '%local tempds colinfo fmtds i numcols stmt_obs; ';
put '%let numcols=0; '; put '%let numcols=0; ';
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
put ' '; put ' ';
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
@@ -180,7 +182,9 @@ data _null_;
put ' %put &sysmacroname: Switching to DATASTEP engine; '; put ' %put &sysmacroname: Switching to DATASTEP engine; ';
put ' %goto datastep; '; put ' %goto datastep; ';
put ' %end; '; put ' %end; ';
put ' data &tempds;set &ds; '; put ' data &tempds; ';
put ' set &ds; ';
put ' &stmt_obs; ';
put ' %if &fmt=N %then format _numeric_ best32.;; '; put ' %if &fmt=N %then format _numeric_ best32.;; ';
put ' /* PRETTY is necessary to avoid line truncation in large files */ '; put ' /* PRETTY is necessary to avoid line truncation in large files */ ';
put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
@@ -255,6 +259,7 @@ data _null_;
put ' %else %do; '; put ' %else %do; ';
put ' set &ds; '; put ' set &ds; ';
put ' %end; '; put ' %end; ';
put ' &stmt_obs; ';
put ' format _numeric_ bart.; '; put ' format _numeric_ bart.; ';
put ' %do i=1 %to &numcols; '; put ' %do i=1 %to &numcols; ';
put ' %if &&typelong&i=char or &fmt=Y %then %do; '; put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
@@ -311,10 +316,11 @@ data _null_;
put ' proc sql; '; put ' proc sql; ';
put ' drop table &colinfo, &tempds; '; put ' drop table &colinfo, &tempds; ';
put ' '; put ' ';
put ' %if &showmeta=YES %then %do; '; put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
put ' data _null_; '; put ' data _null_; ';
put ' file _sjs4; '; put ' file _sjs4; ';
put ' length label $350; ';
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; '; put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
put ' do i=1 to &numcols; '; put ' do i=1 to &numcols; ';
put ' name=quote(trim(symget(cats(''name'',i)))); '; put ' name=quote(trim(symget(cats(''name'',i)))); ';
@@ -368,7 +374,7 @@ data _null_;
put '%mend mf_getuser; '; put '%mend mf_getuser; ';
put ' '; put ' ';
put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL '; put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put '); '; put '); ';
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug '; put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
put ' sasjs_tables; '; put ' sasjs_tables; ';
@@ -433,7 +439,6 @@ data _null_;
put '%else %if &action=CLOSE %then %do; '; put '%else %if &action=CLOSE %then %do; ';
put ' %if %str(&_debug) ge 131 %then %do; '; put ' %if %str(&_debug) ge 131 %then %do; ';
put ' /* if debug mode, send back first 10 records of each work table also */ '; put ' /* if debug mode, send back first 10 records of each work table also */ ';
put ' options obs=10; ';
put ' data;run;%let tempds=%scan(&syslast,2,.); '; put ' data;run;%let tempds=%scan(&syslast,2,.); ';
put ' ods output Members=&tempds; '; put ' ods output Members=&tempds; ';
put ' proc datasets library=WORK memtype=data; '; put ' proc datasets library=WORK memtype=data; ';
@@ -458,7 +463,7 @@ data _null_;
put ' put " ""&wt"" : {"; '; put ' put " ""&wt"" : {"; ';
put ' put ''"nlobs":'' nlobs; '; put ' put ''"nlobs":'' nlobs; ';
put ' put '',"nvars":'' nvars; '; put ' put '',"nvars":'' nvars; ';
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) '; put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; '; put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
put ' put "}"; '; put ' put "}"; ';
put ' %end; '; put ' %end; ';
@@ -475,7 +480,7 @@ data _null_;
put ' put '',"_PROGRAM" : '' _PROGRAM ; '; put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' put ",""SYSENCODING"" : ""&sysencoding"" "; '; put ' put ",""SYSENCODING"" : ""&sysencoding"" "; ';
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); '; put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
put ' put '',"SYSERRORTEXT" : '' syserrortext; '; put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
put ' SYSHOSTINFOLONG=quote(trim(symget(''SYSHOSTINFOLONG''))); '; put ' SYSHOSTINFOLONG=quote(trim(symget(''SYSHOSTINFOLONG''))); ';
put ' put '',"SYSHOSTINFOLONG" : '' SYSHOSTINFOLONG; '; put ' put '',"SYSHOSTINFOLONG" : '' SYSHOSTINFOLONG; ';
@@ -491,7 +496,7 @@ data _null_;
put ' put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; '; put ' put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); '; put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; '; put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; '; put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
put ' length autoexec $512; '; put ' length autoexec $512; ';

View File

@@ -116,14 +116,16 @@ libname &libref JSON fileref=&fref1;
%if "&group"="0" and "&gid"="0" %then %do; %if "&group"="0" and "&gid"="0" %then %do;
data &outds; data &outds;
length DISPLAYNAME $60 USERNAME:$30 ID 8; length DISPLAYNAME $60 USERNAME:$30 ID 8;
set &libref..root; if nobs=0 then call missing(of _all_);
set &libref..root nobs=nobs;
drop ordinal_root; drop ordinal_root;
run; run;
%end; %end;
%else %do; %else %do;
data &outds; data &outds;
length DISPLAYNAME $60 USERNAME:$30 ID 8; length DISPLAYNAME $60 USERNAME:$30 ID 8;
set &libref..users; if nobs=0 then call missing(of _all_);
set &libref..users nobs=nobs;
drop ordinal_root ordinal_users; drop ordinal_root ordinal_users;
run; run;
%end; %end;

View File

@@ -27,7 +27,7 @@
@param [out] fref= (_webout) The fileref to which to write the JSON @param [out] fref= (_webout) The fileref to which to write the JSON
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@@ -47,7 +47,7 @@
**/ **/
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL %macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
,showmeta=NO ,showmeta=N
); );
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug %global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
sasjs_tables; sasjs_tables;
@@ -112,7 +112,6 @@
%else %if &action=CLOSE %then %do; %else %if &action=CLOSE %then %do;
%if %str(&_debug) ge 131 %then %do; %if %str(&_debug) ge 131 %then %do;
/* if debug mode, send back first 10 records of each work table also */ /* if debug mode, send back first 10 records of each work table also */
options obs=10;
data;run;%let tempds=%scan(&syslast,2,.); data;run;%let tempds=%scan(&syslast,2,.);
ods output Members=&tempds; ods output Members=&tempds;
proc datasets library=WORK memtype=data; proc datasets library=WORK memtype=data;
@@ -137,7 +136,7 @@
put " ""&wt"" : {"; put " ""&wt"" : {";
put '"nlobs":' nlobs; put '"nlobs":' nlobs;
put ',"nvars":' nvars; put ',"nvars":' nvars;
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
data _null_; file &fref mod encoding='utf-8' termstr=lf; data _null_; file &fref mod encoding='utf-8' termstr=lf;
put "}"; put "}";
%end; %end;
@@ -154,7 +153,7 @@
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
put ",""SYSENCODING"" : ""&sysencoding"" "; put ",""SYSENCODING"" : ""&sysencoding"" ";
syserrortext=quote(cats(symget('SYSERRORTEXT'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ',"SYSERRORTEXT" : ' syserrortext; put ',"SYSERRORTEXT" : ' syserrortext;
SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG'))); SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG')));
put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG; put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG;
@@ -170,7 +169,7 @@
put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(cats(symget('SYSWARNINGTEXT'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ',"SYSWARNINGTEXT" : ' syswarningtext; put ',"SYSWARNINGTEXT" : ' syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
length autoexec $512; length autoexec $512;

View File

@@ -0,0 +1,35 @@
/**
@file
@brief Testing mf_increment macro
<h4> SAS Macros </h4>
@li mf_increment.sas
@li mp_assert.sas
**/
%let var=0;
%mp_assert(
iftrue=(
"%mf_increment(var)"="1"
),
desc=Checking basic mf_increment usage 1,
outds=work.test_results
)
%mp_assert(
iftrue=(
"%mf_increment(var)"="2"
),
desc=Checking basic mf_increment usage 2,
outds=work.test_results
)
%mp_assert(
iftrue=(
"%mf_increment(var,incr=2)"="4"
),
desc=Checking incr option,
outds=work.test_results
)

View File

@@ -38,7 +38,7 @@ William,M,15,66.5,112
;;;; ;;;;
run; run;
/* valid filter conditions */ /* VALID filter conditions */
data work.inds; data work.inds;
infile datalines4 dsd; infile datalines4 dsd;
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
@@ -51,6 +51,9 @@ AND,OR,2,Weight,>=,77.7
AND,OR,2,Weight,NE,77.7 AND,OR,2,Weight,NE,77.7
AND,AND,1,age,=,.A AND,AND,1,age,=,.A
AND,AND,1,height,<,.B AND,AND,1,height,<,.B
AND,AND,1,age,IN,"(.a,.b,.)"
AND,AND,1,age,IN,"(.A)"
;;;; ;;;;
run; run;
@@ -115,6 +118,28 @@ run;
outds=work.test_results outds=work.test_results
) )
/* invalid IN value */
data work.inds;
infile datalines4 dsd;
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
OPERATOR_NM:$10. RAW_VALUE:$4000.;
datalines4;
AND,OR,2,age,IN,"(.,.a,X)"
;;;;
run;
%mp_filtercheck(work.inds,
targetds=work.class,
outds=work.badrecords,
abort=NO
)
%let syscc=0;
%mp_assertdsobs(work.badrecords,
desc=Invalid IN value,
test=HASOBS,
outds=work.test_results
)
/* Code injection - column name */ /* Code injection - column name */
data work.inds; data work.inds;
infile datalines4 dsd; infile datalines4 dsd;
@@ -163,7 +188,7 @@ run;
data work.inds; data work.inds;
infile datalines4 dsd; infile datalines4 dsd;
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
OPERATOR_NM:$10. RAW_VALUE:8; OPERATOR_NM:$10. RAW_VALUE:8.;
datalines4; datalines4;
AND,AND,1,age,=,0 AND,AND,1,age,=,0
;;;; ;;;;

View File

@@ -56,6 +56,9 @@ AND,AND,1,SEX,<=,"'M'"
AND,OR,2,Name,NOT IN,"('Jane','Alfred')" AND,OR,2,Name,NOT IN,"('Jane','Alfred')"
AND,OR,2,Weight,>=,77.7 AND,OR,2,Weight,>=,77.7
AND,OR,2,Weight,NE,77.7 AND,OR,2,Weight,NE,77.7
AND,AND,3,age,NOT IN,"(.a,.b,.)"
AND,AND,3,age,NOT IN,"(.A)"
AND,AND,4,Name,=,"'Jeremiah'"
;;;; ;;;;
run; run;

View File

@@ -240,10 +240,12 @@ data _null_;
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y '; put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
put ' ,engine=DATASTEP '; put ' ,engine=DATASTEP ';
put ' ,missing=NULL '; put ' ,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put ' ,maxobs=MAX ';
put ')/*/STORE SOURCE*/; '; put ')/*/STORE SOURCE*/; ';
put '%local tempds colinfo fmtds i numcols; '; put '%local tempds colinfo fmtds i numcols stmt_obs; ';
put '%let numcols=0; '; put '%let numcols=0; ';
put '%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
put ' '; put ' ';
put '%if &action=OPEN %then %do; '; put '%if &action=OPEN %then %do; ';
put ' options nobomfile; '; put ' options nobomfile; ';
@@ -322,7 +324,9 @@ data _null_;
put ' %put &sysmacroname: Switching to DATASTEP engine; '; put ' %put &sysmacroname: Switching to DATASTEP engine; ';
put ' %goto datastep; '; put ' %goto datastep; ';
put ' %end; '; put ' %end; ';
put ' data &tempds;set &ds; '; put ' data &tempds; ';
put ' set &ds; ';
put ' &stmt_obs; ';
put ' %if &fmt=N %then format _numeric_ best32.;; '; put ' %if &fmt=N %then format _numeric_ best32.;; ';
put ' /* PRETTY is necessary to avoid line truncation in large files */ '; put ' /* PRETTY is necessary to avoid line truncation in large files */ ';
put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
@@ -397,6 +401,7 @@ data _null_;
put ' %else %do; '; put ' %else %do; ';
put ' set &ds; '; put ' set &ds; ';
put ' %end; '; put ' %end; ';
put ' &stmt_obs; ';
put ' format _numeric_ bart.; '; put ' format _numeric_ bart.; ';
put ' %do i=1 %to &numcols; '; put ' %do i=1 %to &numcols; ';
put ' %if &&typelong&i=char or &fmt=Y %then %do; '; put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
@@ -453,10 +458,11 @@ data _null_;
put ' proc sql; '; put ' proc sql; ';
put ' drop table &colinfo, &tempds; '; put ' drop table &colinfo, &tempds; ';
put ' '; put ' ';
put ' %if &showmeta=YES %then %do; '; put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; '; put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
put ' data _null_; '; put ' data _null_; ';
put ' file _sjs4; '; put ' file _sjs4; ';
put ' length label $350; ';
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; '; put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
put ' do i=1 to &numcols; '; put ' do i=1 to &numcols; ';
put ' name=quote(trim(symget(cats(''name'',i)))); '; put ' name=quote(trim(symget(cats(''name'',i)))); ';
@@ -509,7 +515,7 @@ data _null_;
put ' '; put ' ';
put '%mend mf_getuser; '; put '%mend mf_getuser; ';
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL '; put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL ';
put ' ,showmeta=NO '; put ' ,showmeta=N ';
put '); '; put '); ';
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name '; put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
put ' sasjs_tables SYS_JES_JOB_URI; '; put ' sasjs_tables SYS_JES_JOB_URI; ';
@@ -601,8 +607,7 @@ data _null_;
put ' '; put ' ';
put ' /* setup temp ref */ '; put ' /* setup temp ref */ ';
put ' %if %upcase(&fref) ne _WEBOUT %then %do; '; put ' %if %upcase(&fref) ne _WEBOUT %then %do; ';
put ' filename &fref temp lrecl=999999 permission=''A::u::rwx,A::g::rw-,A::o::---'' '; put ' filename &fref temp lrecl=999999 permission=''A::u::rwx,A::g::rw-,A::o::---''; ';
put ' mod; ';
put ' %end; '; put ' %end; ';
put ' '; put ' ';
put ' /* setup json */ '; put ' /* setup json */ ';
@@ -619,7 +624,6 @@ data _null_;
put '%else %if &action=CLOSE %then %do; '; put '%else %if &action=CLOSE %then %do; ';
put ' %if %str(&_debug) ge 131 %then %do; '; put ' %if %str(&_debug) ge 131 %then %do; ';
put ' /* send back first 10 records of each work table for debugging */ '; put ' /* send back first 10 records of each work table for debugging */ ';
put ' options obs=10; ';
put ' data;run;%let tempds=%scan(&syslast,2,.); '; put ' data;run;%let tempds=%scan(&syslast,2,.); ';
put ' ods output Members=&tempds; '; put ' ods output Members=&tempds; ';
put ' proc datasets library=WORK memtype=data; '; put ' proc datasets library=WORK memtype=data; ';
@@ -642,7 +646,7 @@ data _null_;
put ' put " ""&wt"" : {"; '; put ' put " ""&wt"" : {"; ';
put ' put ''"nlobs":'' nlobs; '; put ' put ''"nlobs":'' nlobs; ';
put ' put '',"nvars":'' nvars; '; put ' put '',"nvars":'' nvars; ';
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) '; put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10) ';
put ' data _null_; file &fref mod;put "}"; '; put ' data _null_; file &fref mod;put "}"; ';
put ' %end; '; put ' %end; ';
put ' data _null_; file &fref mod;put "}";run; '; put ' data _null_; file &fref mod;put "}";run; ';
@@ -659,14 +663,14 @@ data _null_;
put ' put ",""_DEBUG"" : ""&_debug"" "; '; put ' put ",""_DEBUG"" : ""&_debug"" "; ';
put ' put '',"_PROGRAM" : '' _PROGRAM ; '; put ' put '',"_PROGRAM" : '' _PROGRAM ; ';
put ' put ",""SYSCC"" : ""&syscc"" "; '; put ' put ",""SYSCC"" : ""&syscc"" "; ';
put ' syserrortext=quote(cats(symget(''SYSERRORTEXT''))); '; put ' syserrortext=cats(''"'',tranwrd(symget(''syserrortext''),''"'',''\"''),''"''); ';
put ' put '',"SYSERRORTEXT" : '' syserrortext; '; put ' put '',"SYSERRORTEXT" : '' syserrortext; ';
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; '; put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
put ' put ",""SYSSCPL"" : ""&sysscpl"" "; '; put ' put ",""SYSSCPL"" : ""&sysscpl"" "; ';
put ' put ",""SYSSITE"" : ""&syssite"" "; '; put ' put ",""SYSSITE"" : ""&syssite"" "; ';
put ' sysvlong=quote(trim(symget(''sysvlong''))); '; put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
put ' put '',"SYSVLONG" : '' sysvlong; '; put ' put '',"SYSVLONG" : '' sysvlong; ';
put ' syswarningtext=quote(cats(symget(''SYSWARNINGTEXT''))); '; put ' syswarningtext=cats(''"'',tranwrd(symget(''syswarningtext''),''"'',''\"''),''"''); ';
put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; '; put ' put '',"SYSWARNINGTEXT" : '' syswarningtext; ';
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; '; put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
put ' length memsize $32; '; put ' length memsize $32; ';

View File

@@ -29,7 +29,7 @@
@param [in] stream=(Y) Change to N if not streaming to _webout @param [in] stream=(Y) Change to N if not streaming to _webout
@param [in] missing= (NULL) Special numeric missing values can be sent as NULL @param [in] missing= (NULL) Special numeric missing values can be sent as NULL
(eg `null`) or as STRING values (eg `".a"` or `".b"`) (eg `null`) or as STRING values (eg `".a"` or `".b"`)
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table, @param [in] showmeta= (N) Set to Y to output metadata alongside each table,
such as the column formats and types. The metadata is contained inside an such as the column formats and types. The metadata is contained inside an
object with the same name as the table but prefixed with a dollar sign - ie, object with the same name as the table but prefixed with a dollar sign - ie,
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}` `,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
@@ -43,7 +43,7 @@
**/ **/
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL %macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL
,showmeta=NO ,showmeta=N
); );
%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;
@@ -135,8 +135,7 @@
/* setup temp ref */ /* setup temp ref */
%if %upcase(&fref) ne _WEBOUT %then %do; %if %upcase(&fref) ne _WEBOUT %then %do;
filename &fref temp lrecl=999999 permission='A::u::rwx,A::g::rw-,A::o::---' filename &fref temp lrecl=999999 permission='A::u::rwx,A::g::rw-,A::o::---';
mod;
%end; %end;
/* setup json */ /* setup json */
@@ -153,7 +152,6 @@
%else %if &action=CLOSE %then %do; %else %if &action=CLOSE %then %do;
%if %str(&_debug) ge 131 %then %do; %if %str(&_debug) ge 131 %then %do;
/* send back first 10 records of each work table for debugging */ /* send back first 10 records of each work table for debugging */
options obs=10;
data;run;%let tempds=%scan(&syslast,2,.); data;run;%let tempds=%scan(&syslast,2,.);
ods output Members=&tempds; ods output Members=&tempds;
proc datasets library=WORK memtype=data; proc datasets library=WORK memtype=data;
@@ -176,7 +174,7 @@
put " ""&wt"" : {"; put " ""&wt"" : {";
put '"nlobs":' nlobs; put '"nlobs":' nlobs;
put ',"nvars":' nvars; put ',"nvars":' nvars;
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y,maxobs=10)
data _null_; file &fref mod;put "}"; data _null_; file &fref mod;put "}";
%end; %end;
data _null_; file &fref mod;put "}";run; data _null_; file &fref mod;put "}";run;
@@ -193,14 +191,14 @@
put ",""_DEBUG"" : ""&_debug"" "; put ",""_DEBUG"" : ""&_debug"" ";
put ',"_PROGRAM" : ' _PROGRAM ; put ',"_PROGRAM" : ' _PROGRAM ;
put ",""SYSCC"" : ""&syscc"" "; put ",""SYSCC"" : ""&syscc"" ";
syserrortext=quote(cats(symget('SYSERRORTEXT'))); syserrortext=cats('"',tranwrd(symget('syserrortext'),'"','\"'),'"');
put ',"SYSERRORTEXT" : ' syserrortext; put ',"SYSERRORTEXT" : ' syserrortext;
put ",""SYSHOSTNAME"" : ""&syshostname"" "; put ",""SYSHOSTNAME"" : ""&syshostname"" ";
put ",""SYSSCPL"" : ""&sysscpl"" "; put ",""SYSSCPL"" : ""&sysscpl"" ";
put ",""SYSSITE"" : ""&syssite"" "; put ",""SYSSITE"" : ""&syssite"" ";
sysvlong=quote(trim(symget('sysvlong'))); sysvlong=quote(trim(symget('sysvlong')));
put ',"SYSVLONG" : ' sysvlong; put ',"SYSVLONG" : ' sysvlong;
syswarningtext=quote(cats(symget('SYSWARNINGTEXT'))); syswarningtext=cats('"',tranwrd(symget('syswarningtext'),'"','\"'),'"');
put ',"SYSWARNINGTEXT" : ' syswarningtext; put ',"SYSWARNINGTEXT" : ' syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" '; put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
length memsize $32; length memsize $32;