mirror of
https://github.com/sasjs/core.git
synced 2026-01-05 00:20:05 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4307bfb1b5 | ||
|
|
df46ee6939 | ||
|
|
70b9b71104 | ||
|
|
cd33355418 | ||
|
|
77d1cdb753 | ||
|
|
545218e3b9 | ||
|
|
cb07305a87 | ||
|
|
76a39cad20 | ||
|
|
ebd567af48 | ||
|
|
a9c418e3f2 | ||
|
|
e143acd67d | ||
|
|
84eb2f1845 | ||
|
|
b075e5d5d5 |
@@ -188,6 +188,13 @@ When contributing to this library, it is therefore important to ensure that all
|
|||||||
|
|
||||||
- All macros should be compatible with SAS versions from support level B and above (so currently 9.2 and later). If an earlier version is not supported, then the macro should say as such in the header documentation, and exit gracefully (eg `%if %sysevalf(&sysver<9.3) %then %return`).
|
- All macros should be compatible with SAS versions from support level B and above (so currently 9.2 and later). If an earlier version is not supported, then the macro should say as such in the header documentation, and exit gracefully (eg `%if %sysevalf(&sysver<9.3) %then %return`).
|
||||||
|
|
||||||
|
## Breaking Changes
|
||||||
|
|
||||||
|
We are currently on major release v3. The following changes are planned when the next major (breaking) release becomes necessary:
|
||||||
|
|
||||||
|
* Remove `dbg` parameter from mp_jsonout.sas (implement mdebug instead)
|
||||||
|
* Remove `END_DTTM` and `START_DTTM` from mx_webout JSON
|
||||||
|
|
||||||
## Star Gazing
|
## Star Gazing
|
||||||
|
|
||||||
If you find this library useful, please leave a [star](https://github.com/sasjs/core/stargazers) and help us grow our star graph!
|
If you find this library useful, please leave a [star](https://github.com/sasjs/core/stargazers) and help us grow our star graph!
|
||||||
|
|||||||
@@ -19,11 +19,12 @@
|
|||||||
|
|
||||||
%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(CLOSE,jref=tmp)
|
%mp_jsonout(CLOSE,jref=tmp)
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
infile tmp;
|
infile tmp;
|
||||||
input;list;
|
input;putlog _infile_;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
If you are building web apps with SAS then you are strongly encouraged to use
|
If you are building web apps with SAS then you are strongly encouraged to use
|
||||||
@@ -31,22 +32,24 @@
|
|||||||
[sasjs adapter](https://github.com/sasjs/adapter).
|
[sasjs adapter](https://github.com/sasjs/adapter).
|
||||||
For more information see https://sasjs.io
|
For more information see https://sasjs.io
|
||||||
|
|
||||||
@param action Valid values:
|
@param [in] action Valid values:
|
||||||
@li OPEN - opens the JSON
|
@li OPEN - opens the JSON
|
||||||
@li OBJ - sends a table with each row as an object
|
@li OBJ - sends a table with each row as an object
|
||||||
@li ARR - sends a table with each row in an array
|
@li ARR - sends a table with each row in an array
|
||||||
@li CLOSE - closes the JSON
|
@li CLOSE - closes the JSON
|
||||||
|
@param [in] ds The dataset to send. Must be a work table.
|
||||||
@param ds the dataset to send. Must be a work table.
|
@param [out] jref= (_webout) The fileref to which to send the JSON
|
||||||
@param jref= the fileref to which to send the JSON
|
@param [out] dslabel= The name to give the table in the exported JSON
|
||||||
@param dslabel= the name to give the table in the exported JSON
|
@param [in] fmt= (Y) Whether to keep (Y) or strip (N) formats from the table
|
||||||
@param fmt= Whether to keep or strip formats from the table
|
@param [in] engine= (DATASTEP) Which engine to use to send the JSON. Options:
|
||||||
@param engine= Which engine to use to send the JSON, valid options are:
|
|
||||||
@li PROCJSON (default)
|
@li PROCJSON (default)
|
||||||
@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 dbg= DEPRECATED - was used to conditionally add PRETTY to
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
proc json but this can cause line truncation in large files.
|
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table,
|
||||||
|
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,
|
||||||
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
|
||||||
<h4> Related Macros <h4>
|
<h4> Related Macros <h4>
|
||||||
@li mp_ds2fmtds.sas
|
@li mp_ds2fmtds.sas
|
||||||
@@ -57,9 +60,15 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=DATASTEP,dbg=0
|
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y
|
||||||
|
,engine=DATASTEP
|
||||||
|
,dbg=0 /* DEPRECATED */
|
||||||
|
,missing=NULL
|
||||||
|
,showmeta=NO
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%put output location=&jref;
|
%local tempds colinfo fmtds i numcols;
|
||||||
|
%let numcols=0;
|
||||||
|
|
||||||
%if &action=OPEN %then %do;
|
%if &action=OPEN %then %do;
|
||||||
options nobomfile;
|
options nobomfile;
|
||||||
data _null_;file &jref encoding='utf-8' ;
|
data _null_;file &jref encoding='utf-8' ;
|
||||||
@@ -68,118 +77,124 @@
|
|||||||
%end;
|
%end;
|
||||||
%else %if (&action=ARR or &action=OBJ) %then %do;
|
%else %if (&action=ARR or &action=OBJ) %then %do;
|
||||||
options validvarname=upcase;
|
options validvarname=upcase;
|
||||||
data _null_;file &jref mod encoding='utf-8' ;
|
data _null_; file &jref encoding='utf-8' mod;
|
||||||
put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":";
|
put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":";
|
||||||
|
|
||||||
|
/* grab col defs */
|
||||||
|
proc contents noprint data=&ds
|
||||||
|
out=_data_(keep=name type length format formatl formatd varnum label);
|
||||||
|
run;
|
||||||
|
%let colinfo=%scan(&syslast,2,.);
|
||||||
|
proc sort data=&colinfo;
|
||||||
|
by varnum;
|
||||||
|
run;
|
||||||
|
/* move meta to mac vars */
|
||||||
|
data _null_;
|
||||||
|
if _n_=1 then call symputx('numcols',nobs,'l');
|
||||||
|
set &colinfo end=last nobs=nobs;
|
||||||
|
name=upcase(name);
|
||||||
|
/* fix formats */
|
||||||
|
if type=2 or type=6 then do;
|
||||||
|
typelong='char';
|
||||||
|
length fmt $49.;
|
||||||
|
if format='' then fmt=cats('$',length,'.');
|
||||||
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
|
else fmt=cats(format,formatl,'.');
|
||||||
|
newlen=max(formatl,length);
|
||||||
|
end;
|
||||||
|
else do;
|
||||||
|
typelong='num';
|
||||||
|
if format='' then fmt='best.';
|
||||||
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
|
else if formatd=0 then fmt=cats(format,formatl,'.');
|
||||||
|
else fmt=cats(format,formatl,'.',formatd);
|
||||||
|
/* needs to be wide, for datetimes etc */
|
||||||
|
newlen=max(length,formatl,24);
|
||||||
|
end;
|
||||||
|
/* 32 char unique name */
|
||||||
|
newname='sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
|
||||||
|
|
||||||
|
call symputx(cats('name',_n_),name,'l');
|
||||||
|
call symputx(cats('newname',_n_),newname,'l');
|
||||||
|
call symputx(cats('len',_n_),newlen,'l');
|
||||||
|
call symputx(cats('length',_n_),length,'l');
|
||||||
|
call symputx(cats('fmt',_n_),fmt,'l');
|
||||||
|
call symputx(cats('type',_n_),type,'l');
|
||||||
|
call symputx(cats('typelong',_n_),typelong,'l');
|
||||||
|
call symputx(cats('label',_n_),coalescec(label,name),'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
%let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32);
|
||||||
|
|
||||||
%if &engine=PROCJSON %then %do;
|
%if &engine=PROCJSON %then %do;
|
||||||
data;run;%let tempds=&syslast;
|
%if &missing=STRING %then %do;
|
||||||
proc sql;drop table &tempds;
|
%put &sysmacroname: Special Missings not supported in proc json.;
|
||||||
|
%put &sysmacroname: Switching to DATASTEP engine;
|
||||||
|
%goto datastep;
|
||||||
|
%end;
|
||||||
data &tempds /view=&tempds;set &ds;
|
data &tempds /view=&tempds;set &ds;
|
||||||
%if &fmt=N %then format _numeric_ best32.;;
|
%if &fmt=N %then format _numeric_ best32.;;
|
||||||
|
/* PRETTY is necessary to avoid line truncation in large files */
|
||||||
proc json out=&jref pretty
|
proc json out=&jref pretty
|
||||||
%if &action=ARR %then nokeys ;
|
%if &action=ARR %then nokeys ;
|
||||||
;export &tempds / nosastags fmtnumeric;
|
;export &tempds / nosastags fmtnumeric;
|
||||||
run;
|
run;
|
||||||
proc sql;drop view &tempds;
|
|
||||||
%end;
|
%end;
|
||||||
%else %if &engine=DATASTEP %then %do;
|
%else %if &engine=DATASTEP %then %do;
|
||||||
%local cols i tempds;
|
%datastep:
|
||||||
%let cols=0;
|
%if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1
|
||||||
%if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 %then %do;
|
%then %do;
|
||||||
%put &sysmacroname: &ds NOT FOUND!!!;
|
%put &sysmacroname: &ds NOT FOUND!!!;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
%if &fmt=Y %then %do;
|
|
||||||
%put converting every variable to a formatted variable;
|
|
||||||
/* see mp_ds2fmtds.sas for source */
|
|
||||||
proc contents noprint data=&ds
|
|
||||||
out=_data_(keep=name type length format formatl formatd varnum);
|
|
||||||
run;
|
|
||||||
proc sort;
|
|
||||||
by varnum;
|
|
||||||
run;
|
|
||||||
%local fmtds;
|
|
||||||
%let fmtds=%scan(&syslast,2,.);
|
|
||||||
/* prepare formats and varnames */
|
|
||||||
data _null_;
|
|
||||||
if _n_=1 then call symputx('nobs',nobs,'l');
|
|
||||||
set &fmtds end=last nobs=nobs;
|
|
||||||
name=upcase(name);
|
|
||||||
/* fix formats */
|
|
||||||
if type=2 or type=6 then do;
|
|
||||||
length fmt $49.;
|
|
||||||
if format='' then fmt=cats('$',length,'.');
|
|
||||||
else if formatl=0 then fmt=cats(format,'.');
|
|
||||||
else fmt=cats(format,formatl,'.');
|
|
||||||
newlen=max(formatl,length);
|
|
||||||
end;
|
|
||||||
else do;
|
|
||||||
if format='' then fmt='best.';
|
|
||||||
else if formatl=0 then fmt=cats(format,'.');
|
|
||||||
else if formatd=0 then fmt=cats(format,formatl,'.');
|
|
||||||
else fmt=cats(format,formatl,'.',formatd);
|
|
||||||
/* needs to be wide, for datetimes etc */
|
|
||||||
newlen=max(length,formatl,24);
|
|
||||||
end;
|
|
||||||
/* 32 char unique name */
|
|
||||||
newname='sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
|
|
||||||
|
|
||||||
call symputx(cats('name',_n_),name,'l');
|
%if &fmt=Y %then %do;
|
||||||
call symputx(cats('newname',_n_),newname,'l');
|
data _data_;
|
||||||
call symputx(cats('len',_n_),newlen,'l');
|
|
||||||
call symputx(cats('fmt',_n_),fmt,'l');
|
|
||||||
call symputx(cats('type',_n_),type,'l');
|
|
||||||
run;
|
|
||||||
data &fmtds;
|
|
||||||
/* rename on entry */
|
/* rename on entry */
|
||||||
set &ds(rename=(
|
set &ds(rename=(
|
||||||
%local i;
|
%do i=1 %to &numcols;
|
||||||
%do i=1 %to &nobs;
|
|
||||||
&&name&i=&&newname&i
|
&&name&i=&&newname&i
|
||||||
%end;
|
%end;
|
||||||
));
|
));
|
||||||
%do i=1 %to &nobs;
|
%do i=1 %to &numcols;
|
||||||
length &&name&i $&&len&i;
|
length &&name&i $&&len&i;
|
||||||
&&name&i=left(put(&&newname&i,&&fmt&i));
|
&&name&i=left(put(&&newname&i,&&fmt&i));
|
||||||
drop &&newname&i;
|
drop &&newname&i;
|
||||||
%end;
|
%end;
|
||||||
if _error_ then call symputx('syscc',1012);
|
if _error_ then call symputx('syscc',1012);
|
||||||
run;
|
run;
|
||||||
%let ds=&fmtds;
|
%let fmtds=&syslast;
|
||||||
%end; /* &fmt=Y */
|
%end;
|
||||||
data _null_;file &jref mod encoding='utf-8' ;
|
|
||||||
put "["; call symputx('cols',0,'l');
|
|
||||||
proc sort
|
|
||||||
data=sashelp.vcolumn(where=(libname='WORK' & memname="%upcase(&ds)"))
|
|
||||||
out=_data_;
|
|
||||||
by varnum;
|
|
||||||
|
|
||||||
data _null_;
|
|
||||||
set _last_ end=last;
|
|
||||||
call symputx(cats('name',_n_),name,'l');
|
|
||||||
call symputx(cats('type',_n_),type,'l');
|
|
||||||
call symputx(cats('len',_n_),length,'l');
|
|
||||||
if last then call symputx('cols',_n_,'l');
|
|
||||||
run;
|
|
||||||
|
|
||||||
proc format; /* credit yabwon for special null removal */
|
proc format; /* credit yabwon for special null removal */
|
||||||
value bart ._ - .z = null
|
value bart (default=40)
|
||||||
|
%if &missing=NULL %then %do;
|
||||||
|
._ - .z = null
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
._ = [quote()]
|
||||||
|
. = null
|
||||||
|
.a - .z = [quote()]
|
||||||
|
%end;
|
||||||
other = [best.];
|
other = [best.];
|
||||||
|
|
||||||
data;run; %let tempds=&syslast; /* temp table for spesh char management */
|
|
||||||
proc sql; drop table &tempds;
|
|
||||||
data &tempds/view=&tempds;
|
data &tempds/view=&tempds;
|
||||||
attrib _all_ label='';
|
attrib _all_ label='';
|
||||||
%do i=1 %to &cols;
|
%do i=1 %to &numcols;
|
||||||
%if &&type&i=char %then %do;
|
%if &&typelong&i=char or &fmt=Y %then %do;
|
||||||
length &&name&i $32767;
|
length &&name&i $32767;
|
||||||
format &&name&i $32767.;
|
format &&name&i $32767.;
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
set &ds;
|
%if &fmt=Y %then %do;
|
||||||
|
set &fmtds;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
set &ds;
|
||||||
|
%end;
|
||||||
format _numeric_ bart.;
|
format _numeric_ bart.;
|
||||||
%do i=1 %to &cols;
|
%do i=1 %to &numcols;
|
||||||
%if &&type&i=char %then %do;
|
%if &&typelong&i=char or &fmt=Y %then %do;
|
||||||
&&name&i='"'!!trim(prxchange('s/"/\"/',-1,
|
&&name&i='"'!!trim(prxchange('s/"/\"/',-1,
|
||||||
prxchange('s/'!!'0A'x!!'/\n/',-1,
|
prxchange('s/'!!'0A'x!!'/\n/',-1,
|
||||||
prxchange('s/'!!'0D'x!!'/\r/',-1,
|
prxchange('s/'!!'0D'x!!'/\r/',-1,
|
||||||
@@ -189,44 +204,65 @@
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
/* write to temp loc to avoid _webout truncation
|
/* write to temp loc to avoid _webout truncation
|
||||||
- https://support.sas.com/kb/49/325.html */
|
- https://support.sas.com/kb/49/325.html */
|
||||||
filename _sjs temp lrecl=131068 encoding='utf-8';
|
filename _sjs temp lrecl=131068 encoding='utf-8';
|
||||||
data _null_; file _sjs lrecl=131068 encoding='utf-8' mod ;
|
data _null_; file _sjs lrecl=131068 encoding='utf-8' mod ;
|
||||||
|
if _n_=1 then put "[";
|
||||||
set &tempds;
|
set &tempds;
|
||||||
if _n_>1 then put "," @; put
|
if _n_>1 then put "," @; put
|
||||||
%if &action=ARR %then "[" ; %else "{" ;
|
%if &action=ARR %then "[" ; %else "{" ;
|
||||||
%do i=1 %to &cols;
|
%do i=1 %to &numcols;
|
||||||
%if &i>1 %then "," ;
|
%if &i>1 %then "," ;
|
||||||
%if &action=OBJ %then """&&name&i"":" ;
|
%if &action=OBJ %then """&&name&i"":" ;
|
||||||
&&name&i
|
&&name&i
|
||||||
%end;
|
%end;
|
||||||
%if &action=ARR %then "]" ; %else "}" ; ;
|
%if &action=ARR %then "]" ; %else "}" ; ;
|
||||||
proc sql;
|
|
||||||
drop view &tempds;
|
|
||||||
/* now write the long strings to _webout 1 byte at a time */
|
/* now write the long strings to _webout 1 byte at a time */
|
||||||
data _null_;
|
data _null_;
|
||||||
length filein 8 fileid 8;
|
length filein 8 fileid 8;
|
||||||
filein = fopen("_sjs",'I',1,'B');
|
filein=fopen("_sjs",'I',1,'B');
|
||||||
fileid = fopen("&jref",'A',1,'B');
|
fileid=fopen("&jref",'A',1,'B');
|
||||||
rec = '20'x;
|
rec='20'x;
|
||||||
do while(fread(filein)=0);
|
do while(fread(filein)=0);
|
||||||
rc = fget(filein,rec,1);
|
rc=fget(filein,rec,1);
|
||||||
rc = fput(fileid, rec);
|
rc=fput(fileid, rec);
|
||||||
rc =fwrite(fileid);
|
rc=fwrite(fileid);
|
||||||
end;
|
end;
|
||||||
rc = fclose(filein);
|
/* close out the table */
|
||||||
rc = fclose(fileid);
|
rc=fput(fileid, "]");
|
||||||
|
rc=fwrite(fileid);
|
||||||
|
rc=fclose(filein);
|
||||||
|
rc=fclose(fileid);
|
||||||
run;
|
run;
|
||||||
filename _sjs clear;
|
filename _sjs clear;
|
||||||
data _null_; file &jref mod encoding='utf-8' ;
|
%end;
|
||||||
put "]";
|
|
||||||
|
proc sql;
|
||||||
|
drop view &tempds;
|
||||||
|
drop table &colinfo;
|
||||||
|
|
||||||
|
%if &showmeta=YES %then %do;
|
||||||
|
data _null_; file &jref encoding='utf-8' mod;
|
||||||
|
put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{";
|
||||||
|
do i=1 to &numcols;
|
||||||
|
name=quote(trim(symget(cats('name',i))));
|
||||||
|
format=quote(trim(symget(cats('fmt',i))));
|
||||||
|
label=quote(trim(symget(cats('label',i))));
|
||||||
|
length=quote(trim(symget(cats('length',i))));
|
||||||
|
type=quote(trim(symget(cats('typelong',i))));
|
||||||
|
if i>1 then put "," @@;
|
||||||
|
put name ':{"format":' format ',"label":' label
|
||||||
|
',"length":' length ',"type":' type '}';
|
||||||
|
end;
|
||||||
|
put '}}';
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
data _null_;file &jref encoding='utf-8' mod ;
|
data _null_; file &jref encoding='utf-8' mod ;
|
||||||
put "}";
|
put "}";
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
length is 200 characters.
|
length is 200 characters.
|
||||||
@param [out] ctl_ds= (0) The control table which controls the actual locking.
|
@param [out] ctl_ds= (0) The control table which controls the actual locking.
|
||||||
Should already be assigned and available. The definition is available by
|
Should already be assigned and available. The definition is available by
|
||||||
running mp_coretable.sas as follows: `mp_coretable(LOCKTABLE)`.
|
running mp_coretable.sas as follows: `%mp_coretable(LOCKTABLE)`.
|
||||||
|
|
||||||
@param [in] loops= (25) Number of times to check for a lock.
|
@param [in] loops= (25) Number of times to check for a lock.
|
||||||
@param [in] loop_secs= (1) Seconds to wait between each lock attempt
|
@param [in] loop_secs= (1) Seconds to wait between each lock attempt
|
||||||
|
|||||||
@@ -39,14 +39,6 @@
|
|||||||
,Server=SASApp
|
,Server=SASApp
|
||||||
,stptype=2)
|
,stptype=2)
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
|
||||||
@li mf_nobs.sas
|
|
||||||
@li mf_verifymacvars.sas
|
|
||||||
@li mm_getdirectories.sas
|
|
||||||
@li mm_updatestpsourcecode.sas
|
|
||||||
@li mp_dropmembers.sas
|
|
||||||
@li mm_getservercontexts.sas
|
|
||||||
|
|
||||||
@param stpname= Stored Process name. Avoid spaces - testing has shown that
|
@param stpname= Stored Process name. Avoid spaces - testing has shown that
|
||||||
the check to avoid creating multiple STPs in the same folder with the same
|
the check to avoid creating multiple STPs in the same folder with the same
|
||||||
name does not work when the name contains spaces.
|
name does not work when the name contains spaces.
|
||||||
@@ -77,6 +69,17 @@
|
|||||||
- fileuri
|
- fileuri
|
||||||
- texturi
|
- texturi
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_nobs.sas
|
||||||
|
@li mf_verifymacvars.sas
|
||||||
|
@li mm_getdirectories.sas
|
||||||
|
@li mm_updatestpsourcecode.sas
|
||||||
|
@li mp_dropmembers.sas
|
||||||
|
@li mm_getservercontexts.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mm_createwebservice.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Usage:
|
|||||||
%* parmcards lets us write to a text file from open code ;
|
%* parmcards lets us write to a text file from open code ;
|
||||||
filename ft15f001 temp;
|
filename ft15f001 temp;
|
||||||
parmcards4;
|
parmcards4;
|
||||||
|
%webout(FETCH)
|
||||||
%* do some sas, any inputs are now already WORK tables;
|
%* do some sas, any inputs are now already WORK tables;
|
||||||
data example1 example2;
|
data example1 example2;
|
||||||
set sashelp.class;
|
set sashelp.class;
|
||||||
@@ -24,11 +25,8 @@ Usage:
|
|||||||
;;;;
|
;;;;
|
||||||
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001)
|
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001)
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
For more examples of using these web services with the SASjs Adapter, see:
|
||||||
@li mm_createstp.sas
|
https://github.com/sasjs/adapter#readme
|
||||||
@li mf_getuser.sas
|
|
||||||
@li mm_createfolder.sas
|
|
||||||
@li mm_deletestp.sas
|
|
||||||
|
|
||||||
@param path= The full path (in SAS Metadata) where the service will be created
|
@param path= The full path (in SAS Metadata) where the service will be created
|
||||||
@param name= Stored Process name. Avoid spaces - testing has shown that
|
@param name= Stored Process name. Avoid spaces - testing has shown that
|
||||||
@@ -37,16 +35,22 @@ Usage:
|
|||||||
@param desc= The description of the service (optional)
|
@param desc= The description of the service (optional)
|
||||||
@param precode= Space separated list of filerefs, pointing to the code that
|
@param precode= Space separated list of filerefs, pointing to the code that
|
||||||
needs to be attached to the beginning of the service (optional)
|
needs to be attached to the beginning of the service (optional)
|
||||||
@param code=(ft15f001) Space seperated fileref(s) of the actual code to be
|
@param code= (ft15f001) Space seperated fileref(s) of the actual code to be
|
||||||
added
|
added
|
||||||
@param server=(SASApp) The server which will run the STP. Server name or uri
|
@param server= (SASApp) The server which will run the STP. Server name or uri
|
||||||
is fine.
|
is fine.
|
||||||
@param mDebug=(0) set to 1 to show debug messages in the log
|
@param mDebug= (0) set to 1 to show debug messages in the log
|
||||||
@param replace=(YES) select NO to avoid replacing an existing service in that
|
@param replace= (YES) select NO to avoid replacing an existing service in that
|
||||||
location
|
location
|
||||||
@param adapter=(sasjs) the macro uses the sasjs adapter by default. To use
|
@param adapter= (sasjs) the macro uses the sasjs adapter by default. To use
|
||||||
another adapter, add a (different) fileref here.
|
another adapter, add a (different) fileref here.
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mm_createstp.sas
|
||||||
|
@li mf_getuser.sas
|
||||||
|
@li mm_createfolder.sas
|
||||||
|
@li mm_deletestp.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
@@ -89,9 +93,15 @@ data _null_;
|
|||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=DATASTEP,dbg=0 ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
||||||
|
put ' ,engine=DATASTEP ';
|
||||||
|
put ' ,dbg=0 /* DEPRECATED */ ';
|
||||||
|
put ' ,missing=NULL ';
|
||||||
|
put ' ,showmeta=NO ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%put output location=&jref; ';
|
put '%local tempds colinfo fmtds i numcols; ';
|
||||||
|
put '%let numcols=0; ';
|
||||||
|
put ' ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
put ' options nobomfile; ';
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
||||||
@@ -100,118 +110,124 @@ data _null_;
|
|||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if (&action=ARR or &action=OBJ) %then %do; ';
|
put '%else %if (&action=ARR or &action=OBJ) %then %do; ';
|
||||||
put ' options validvarname=upcase; ';
|
put ' options validvarname=upcase; ';
|
||||||
put ' data _null_;file &jref mod encoding=''utf-8'' ; ';
|
put ' data _null_; file &jref encoding=''utf-8'' mod; ';
|
||||||
put ' put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":"; ';
|
put ' put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":"; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
|
put ' /* grab col defs */ ';
|
||||||
|
put ' proc contents noprint data=&ds ';
|
||||||
|
put ' out=_data_(keep=name type length format formatl formatd varnum label); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' %let colinfo=%scan(&syslast,2,.); ';
|
||||||
|
put ' proc sort data=&colinfo; ';
|
||||||
|
put ' by varnum; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' /* move meta to mac vars */ ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
||||||
|
put ' set &colinfo end=last nobs=nobs; ';
|
||||||
|
put ' name=upcase(name); ';
|
||||||
|
put ' /* fix formats */ ';
|
||||||
|
put ' if type=2 or type=6 then do; ';
|
||||||
|
put ' typelong=''char''; ';
|
||||||
|
put ' length fmt $49.; ';
|
||||||
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' newlen=max(formatl,length); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' else do; ';
|
||||||
|
put ' typelong=''num''; ';
|
||||||
|
put ' if format='''' then fmt=''best.''; ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
|
put ' /* needs to be wide, for datetimes etc */ ';
|
||||||
|
put ' newlen=max(length,formatl,24); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' /* 32 char unique name */ ';
|
||||||
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
|
put ' ';
|
||||||
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
|
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||||
|
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
||||||
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
|
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
||||||
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' ';
|
||||||
put ' %if &engine=PROCJSON %then %do; ';
|
put ' %if &engine=PROCJSON %then %do; ';
|
||||||
put ' data;run;%let tempds=&syslast; ';
|
put ' %if &missing=STRING %then %do; ';
|
||||||
put ' proc sql;drop table &tempds; ';
|
put ' %put &sysmacroname: Special Missings not supported in proc json.; ';
|
||||||
|
put ' %put &sysmacroname: Switching to DATASTEP engine; ';
|
||||||
|
put ' %goto datastep; ';
|
||||||
|
put ' %end; ';
|
||||||
put ' data &tempds /view=&tempds;set &ds; ';
|
put ' data &tempds /view=&tempds;set &ds; ';
|
||||||
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 ' proc json out=&jref pretty ';
|
put ' proc json out=&jref pretty ';
|
||||||
put ' %if &action=ARR %then nokeys ; ';
|
put ' %if &action=ARR %then nokeys ; ';
|
||||||
put ' ;export &tempds / nosastags fmtnumeric; ';
|
put ' ;export &tempds / nosastags fmtnumeric; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql;drop view &tempds; ';
|
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %else %if &engine=DATASTEP %then %do; ';
|
put ' %else %if &engine=DATASTEP %then %do; ';
|
||||||
put ' %local cols i tempds; ';
|
put ' %datastep: ';
|
||||||
put ' %let cols=0; ';
|
put ' %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 ';
|
||||||
put ' %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 %then %do; ';
|
put ' %then %do; ';
|
||||||
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
||||||
put ' %return; ';
|
put ' %return; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
|
||||||
put ' %put converting every variable to a formatted variable; ';
|
|
||||||
put ' /* see mp_ds2fmtds.sas for source */ ';
|
|
||||||
put ' proc contents noprint data=&ds ';
|
|
||||||
put ' out=_data_(keep=name type length format formatl formatd varnum); ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' proc sort; ';
|
|
||||||
put ' by varnum; ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' %local fmtds; ';
|
|
||||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
|
||||||
put ' /* prepare formats and varnames */ ';
|
|
||||||
put ' data _null_; ';
|
|
||||||
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
|
||||||
put ' set &fmtds end=last nobs=nobs; ';
|
|
||||||
put ' name=upcase(name); ';
|
|
||||||
put ' /* fix formats */ ';
|
|
||||||
put ' if type=2 or type=6 then do; ';
|
|
||||||
put ' length fmt $49.; ';
|
|
||||||
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
|
||||||
put ' else fmt=cats(format,formatl,''.''); ';
|
|
||||||
put ' newlen=max(formatl,length); ';
|
|
||||||
put ' end; ';
|
|
||||||
put ' else do; ';
|
|
||||||
put ' if format='''' then fmt=''best.''; ';
|
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
|
||||||
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
|
||||||
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
|
||||||
put ' /* needs to be wide, for datetimes etc */ ';
|
|
||||||
put ' newlen=max(length,formatl,24); ';
|
|
||||||
put ' end; ';
|
|
||||||
put ' /* 32 char unique name */ ';
|
|
||||||
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
put ' data _data_; ';
|
||||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
|
||||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' data &fmtds; ';
|
|
||||||
put ' /* rename on entry */ ';
|
put ' /* rename on entry */ ';
|
||||||
put ' set &ds(rename=( ';
|
put ' set &ds(rename=( ';
|
||||||
put ' %local i; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %do i=1 %to &nobs; ';
|
|
||||||
put ' &&name&i=&&newname&i ';
|
put ' &&name&i=&&newname&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' )); ';
|
put ' )); ';
|
||||||
put ' %do i=1 %to &nobs; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' length &&name&i $&&len&i; ';
|
put ' length &&name&i $&&len&i; ';
|
||||||
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
||||||
put ' drop &&newname&i; ';
|
put ' drop &&newname&i; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' if _error_ then call symputx(''syscc'',1012); ';
|
put ' if _error_ then call symputx(''syscc'',1012); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %let ds=&fmtds; ';
|
put ' %let fmtds=&syslast; ';
|
||||||
put ' %end; /* &fmt=Y */ ';
|
put ' %end; ';
|
||||||
put ' data _null_;file &jref mod encoding=''utf-8'' ; ';
|
|
||||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
|
||||||
put ' proc sort ';
|
|
||||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
|
||||||
put ' out=_data_; ';
|
|
||||||
put ' by varnum; ';
|
|
||||||
put ' ';
|
|
||||||
put ' data _null_; ';
|
|
||||||
put ' set _last_ end=last; ';
|
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
|
||||||
put ' call symputx(cats(''len'',_n_),length,''l''); ';
|
|
||||||
put ' if last then call symputx(''cols'',_n_,''l''); ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc format; /* credit yabwon for special null removal */ ';
|
put ' proc format; /* credit yabwon for special null removal */ ';
|
||||||
put ' value bart ._ - .z = null ';
|
put ' value bart (default=40) ';
|
||||||
|
put ' %if &missing=NULL %then %do; ';
|
||||||
|
put ' ._ - .z = null ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' %else %do; ';
|
||||||
|
put ' ._ = [quote()] ';
|
||||||
|
put ' . = null ';
|
||||||
|
put ' .a - .z = [quote()] ';
|
||||||
|
put ' %end; ';
|
||||||
put ' other = [best.]; ';
|
put ' other = [best.]; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' data;run; %let tempds=&syslast; /* temp table for spesh char management */ ';
|
|
||||||
put ' proc sql; drop table &tempds; ';
|
|
||||||
put ' data &tempds/view=&tempds; ';
|
put ' data &tempds/view=&tempds; ';
|
||||||
put ' attrib _all_ label=''''; ';
|
put ' attrib _all_ label=''''; ';
|
||||||
put ' %do i=1 %to &cols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&type&i=char %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' length &&name&i $32767; ';
|
put ' length &&name&i $32767; ';
|
||||||
put ' format &&name&i $32767.; ';
|
put ' format &&name&i $32767.; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' set &ds; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
|
put ' set &fmtds; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' %else %do; ';
|
||||||
|
put ' set &ds; ';
|
||||||
|
put ' %end; ';
|
||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &cols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&type&i=char %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' &&name&i=''"''!!trim(prxchange(''s/"/\"/'',-1, ';
|
put ' &&name&i=''"''!!trim(prxchange(''s/"/\"/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
||||||
@@ -221,49 +237,72 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
put ' /* write to temp loc to avoid _webout truncation ';
|
put ' /* write to temp loc to avoid _webout truncation ';
|
||||||
put ' - https://support.sas.com/kb/49/325.html */ ';
|
put ' - https://support.sas.com/kb/49/325.html */ ';
|
||||||
put ' filename _sjs temp lrecl=131068 encoding=''utf-8''; ';
|
put ' filename _sjs temp lrecl=131068 encoding=''utf-8''; ';
|
||||||
put ' data _null_; file _sjs lrecl=131068 encoding=''utf-8'' mod ; ';
|
put ' data _null_; file _sjs lrecl=131068 encoding=''utf-8'' mod ; ';
|
||||||
|
put ' if _n_=1 then put "["; ';
|
||||||
put ' set &tempds; ';
|
put ' set &tempds; ';
|
||||||
put ' if _n_>1 then put "," @; put ';
|
put ' if _n_>1 then put "," @; put ';
|
||||||
put ' %if &action=ARR %then "[" ; %else "{" ; ';
|
put ' %if &action=ARR %then "[" ; %else "{" ; ';
|
||||||
put ' %do i=1 %to &cols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &i>1 %then "," ; ';
|
put ' %if &i>1 %then "," ; ';
|
||||||
put ' %if &action=OBJ %then """&&name&i"":" ; ';
|
put ' %if &action=OBJ %then """&&name&i"":" ; ';
|
||||||
put ' &&name&i ';
|
put ' &&name&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &action=ARR %then "]" ; %else "}" ; ; ';
|
put ' %if &action=ARR %then "]" ; %else "}" ; ; ';
|
||||||
put ' proc sql; ';
|
|
||||||
put ' drop view &tempds; ';
|
|
||||||
put ' /* now write the long strings to _webout 1 byte at a time */ ';
|
put ' /* now write the long strings to _webout 1 byte at a time */ ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' length filein 8 fileid 8; ';
|
put ' length filein 8 fileid 8; ';
|
||||||
put ' filein = fopen("_sjs",''I'',1,''B''); ';
|
put ' filein=fopen("_sjs",''I'',1,''B''); ';
|
||||||
put ' fileid = fopen("&jref",''A'',1,''B''); ';
|
put ' fileid=fopen("&jref",''A'',1,''B''); ';
|
||||||
put ' rec = ''20''x; ';
|
put ' rec=''20''x; ';
|
||||||
put ' do while(fread(filein)=0); ';
|
put ' do while(fread(filein)=0); ';
|
||||||
put ' rc = fget(filein,rec,1); ';
|
put ' rc=fget(filein,rec,1); ';
|
||||||
put ' rc = fput(fileid, rec); ';
|
put ' rc=fput(fileid, rec); ';
|
||||||
put ' rc =fwrite(fileid); ';
|
put ' rc=fwrite(fileid); ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' rc = fclose(filein); ';
|
put ' /* close out the table */ ';
|
||||||
put ' rc = fclose(fileid); ';
|
put ' rc=fput(fileid, "]"); ';
|
||||||
|
put ' rc=fwrite(fileid); ';
|
||||||
|
put ' rc=fclose(filein); ';
|
||||||
|
put ' rc=fclose(fileid); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' filename _sjs clear; ';
|
put ' filename _sjs clear; ';
|
||||||
put ' data _null_; file &jref mod encoding=''utf-8'' ; ';
|
put ' %end; ';
|
||||||
put ' put "]"; ';
|
put ' ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' drop view &tempds; ';
|
||||||
|
put ' drop table &colinfo; ';
|
||||||
|
put ' ';
|
||||||
|
put ' %if &showmeta=YES %then %do; ';
|
||||||
|
put ' data _null_; file &jref encoding=''utf-8'' mod; ';
|
||||||
|
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
||||||
|
put ' do i=1 to &numcols; ';
|
||||||
|
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
||||||
|
put ' format=quote(trim(symget(cats(''fmt'',i)))); ';
|
||||||
|
put ' label=quote(trim(symget(cats(''label'',i)))); ';
|
||||||
|
put ' length=quote(trim(symget(cats(''length'',i)))); ';
|
||||||
|
put ' type=quote(trim(symget(cats(''typelong'',i)))); ';
|
||||||
|
put ' if i>1 then put "," @@; ';
|
||||||
|
put ' put name '':{"format":'' format '',"label":'' label ';
|
||||||
|
put ' '',"length":'' length '',"type":'' type ''}''; ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' put ''}}''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' mod ; ';
|
put ' data _null_; file &jref encoding=''utf-8'' mod ; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%mend mp_jsonout; ';
|
put '%mend mp_jsonout; ';
|
||||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL ';
|
||||||
|
put ' ,showmeta=NO ';
|
||||||
|
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; ';
|
||||||
put '%local i tempds jsonengine; ';
|
put '%local i tempds jsonengine; ';
|
||||||
@@ -321,14 +360,15 @@ data _null_;
|
|||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&_debug) ge 131 %then %do; ';
|
||||||
put ' put ''>>weboutBEGIN<<''; ';
|
put ' put ''>>weboutBEGIN<<''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; ';
|
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||||
|
put ' put '',"SYSTIME" : "'' "&SYSTIME" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||||
put ' ,engine=&jsonengine,dbg=%str(&_debug) ';
|
put ' ,engine=&jsonengine,missing=&missing,showmeta=&showmeta ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
@@ -349,9 +389,6 @@ data _null_;
|
|||||||
put ' put ",""WORK"":{"; ';
|
put ' put ",""WORK"":{"; ';
|
||||||
put ' %do i=1 %to &wtcnt; ';
|
put ' %do i=1 %to &wtcnt; ';
|
||||||
put ' %let wt=&&wt&i; ';
|
put ' %let wt=&&wt&i; ';
|
||||||
put ' proc contents noprint data=&wt ';
|
|
||||||
put ' out=_data_ (keep=name type length format:); ';
|
|
||||||
put ' run;%let tempds=%scan(&syslast,2,.); ';
|
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
||||||
put ' dsid=open("WORK.&wt",''is''); ';
|
put ' dsid=open("WORK.&wt",''is''); ';
|
||||||
put ' nlobs=attrn(dsid,''NLOBS''); ';
|
put ' nlobs=attrn(dsid,''NLOBS''); ';
|
||||||
@@ -361,8 +398,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,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine) ';
|
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -391,6 +427,9 @@ data _null_;
|
|||||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||||
|
put ' memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)"; ';
|
||||||
|
put ' memsize=quote(cats(memsize)); ';
|
||||||
|
put ' put '',"MEMSIZE" : '' memsize; ';
|
||||||
put ' put "}" @; ';
|
put ' put "}" @; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&_debug) ge 131 %then %do; ';
|
||||||
put ' put ''>>weboutEND<<''; ';
|
put ' put ''>>weboutEND<<''; ';
|
||||||
@@ -418,8 +457,10 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%mend mf_getuser; ';
|
put '%mend mf_getuser; ';
|
||||||
/* WEBOUT END */
|
/* WEBOUT END */
|
||||||
put '%macro webout(action,ds,dslabel=,fmt=);';
|
put '%macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);';
|
||||||
put ' %mm_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt)';
|
put ' %mm_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing';
|
||||||
|
put ' ,showmeta=&showmeta';
|
||||||
|
put ' )';
|
||||||
put '%mend;';
|
put '%mend;';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,25 @@
|
|||||||
%mm_webout(CLOSE)
|
%mm_webout(CLOSE)
|
||||||
|
|
||||||
|
|
||||||
@param action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
@param [in] action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
||||||
@param ds The dataset to send back to the frontend
|
@param [in] ds The dataset to send back to the frontend
|
||||||
@param dslabel= value to use instead of the real name for sending to JSON
|
@param [out] dslabel= Value to use instead of table name for sending to JSON
|
||||||
@param fmt=(Y) Set to N to send back unformatted values
|
@param [in] fmt=(Y) Set to N to send back unformatted values
|
||||||
@param 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
|
||||||
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
|
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table,
|
||||||
|
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,
|
||||||
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
|
||||||
@version 9.3
|
@version 9.3
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y);
|
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
|
||||||
|
,showmeta=NO
|
||||||
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
%local i tempds jsonengine;
|
%local i tempds jsonengine;
|
||||||
@@ -91,14 +99,15 @@
|
|||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
put '>>weboutBEGIN<<';
|
put '>>weboutBEGIN<<';
|
||||||
%end;
|
%end;
|
||||||
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||||
|
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%else %if &action=ARR or &action=OBJ %then %do;
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
,engine=&jsonengine,dbg=%str(&_debug)
|
,engine=&jsonengine,missing=&missing,showmeta=&showmeta
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
@@ -119,9 +128,6 @@
|
|||||||
put ",""WORK"":{";
|
put ",""WORK"":{";
|
||||||
%do i=1 %to &wtcnt;
|
%do i=1 %to &wtcnt;
|
||||||
%let wt=&&wt&i;
|
%let wt=&&wt&i;
|
||||||
proc contents noprint data=&wt
|
|
||||||
out=_data_ (keep=name type length format:);
|
|
||||||
run;%let tempds=%scan(&syslast,2,.);
|
|
||||||
data _null_; file &fref mod encoding='utf-8';
|
data _null_; file &fref mod encoding='utf-8';
|
||||||
dsid=open("WORK.&wt",'is');
|
dsid=open("WORK.&wt",'is');
|
||||||
nlobs=attrn(dsid,'NLOBS');
|
nlobs=attrn(dsid,'NLOBS');
|
||||||
@@ -131,8 +137,7 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES)
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine)
|
|
||||||
data _null_; file &fref mod encoding='utf-8';
|
data _null_; file &fref mod encoding='utf-8';
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
@@ -161,6 +166,9 @@
|
|||||||
put ',"SYSVLONG" : ' sysvlong;
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||||
|
memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)";
|
||||||
|
memsize=quote(cats(memsize));
|
||||||
|
put ',"MEMSIZE" : ' memsize;
|
||||||
put "}" @;
|
put "}" @;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
put '>>weboutEND<<';
|
put '>>weboutEND<<';
|
||||||
|
|||||||
90
package-lock.json
generated
90
package-lock.json
generated
@@ -10,13 +10,13 @@
|
|||||||
"ts-loader": "^9.2.6"
|
"ts-loader": "^9.2.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sasjs/cli": "^2.39.0"
|
"@sasjs/cli": "^3.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/adapter": {
|
"node_modules/@sasjs/adapter": {
|
||||||
"version": "2.12.0",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-2.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-3.3.1.tgz",
|
||||||
"integrity": "sha512-zzIuohhR8KUDl3DfIFOW38gv3LADPnOBCLOvLoKu4hH5R/UJDkjZ/Gdgc8B35vI7aOprYOLK/T5D/Z44OaTkqw==",
|
"integrity": "sha512-rmdOG+sjmwGipq1AHczwEXNUlzRFV5efj89neVVJWQMZR6JBC1O6Dr9HjEyJHPKcnQ6z3vzH9rRA2PGi5lgMhA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -29,16 +29,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/cli": {
|
"node_modules/@sasjs/cli": {
|
||||||
"version": "2.39.0",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-2.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-3.4.1.tgz",
|
||||||
"integrity": "sha512-n2LcU4n0QCEbUpXqZnBz/Ey5Td0nMJmgJpZRymMGfYEM0Y0x/CeXemd+kXHPjUvgQ+FX+SQzcvUQTEY/YlT4hA==",
|
"integrity": "sha512-voc0/h8bkRAqrj7Pu1egYfCOSFLlLrrh9bXVLuGvSvWK81MezRZnWciTHlQGc9BgO2wU+LrQ0baIMd6u/HMB5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/adapter": "2.12.0",
|
"@sasjs/adapter": "3.3.1",
|
||||||
"@sasjs/core": "2.45.2",
|
"@sasjs/core": "^3.8.0",
|
||||||
"@sasjs/lint": "1.11.2",
|
"@sasjs/lint": "1.11.2",
|
||||||
"@sasjs/utils": "2.32.0",
|
"@sasjs/utils": "2.34.1",
|
||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"csv-stringify": "5.6.5",
|
"csv-stringify": "5.6.5",
|
||||||
"dotenv": "10.0.0",
|
"dotenv": "10.0.0",
|
||||||
@@ -62,10 +62,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/core": {
|
"node_modules/@sasjs/core": {
|
||||||
"version": "2.45.2",
|
"version": "3.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-2.45.2.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-3.8.1.tgz",
|
||||||
"integrity": "sha512-tg+oZCD8GFMXsg+vDL66LMnyU+t151Hrqd7yl+pMXH2qwkA14N/j6QdkTBZOchskqOA/3PnpOlAZN/xxMW2gdg==",
|
"integrity": "sha512-Yxak+WZwh8Z9IKcbi7aDDTRCcKlI6IUp7Ujavkec5pWMj3a2FSlLxu23lY2ERTBe7wMCGiaU7AseWlKcgd5joA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ts-loader": "^9.2.6"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/lint": {
|
"node_modules/@sasjs/lint": {
|
||||||
"version": "1.11.2",
|
"version": "1.11.2",
|
||||||
@@ -77,9 +80,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sasjs/utils": {
|
"node_modules/@sasjs/utils": {
|
||||||
"version": "2.32.0",
|
"version": "2.34.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.34.1.tgz",
|
||||||
"integrity": "sha512-xnvdEuI4PhTtulcdDEIMK7IxVj9bOMU1JTnxRuSEKWcsclY9P9Fw3cnMOOEgXCDffrOPn3f54DP7Wb1GXd+f8g==",
|
"integrity": "sha512-hd1qieH3d7+xH96n5DpRGTEazeAhYyBBKCdnKhOXMgF2TZVoHFdRs5REfT88CKza6DHBGRVGnIVm5ORGP4cVLg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -89,8 +92,11 @@
|
|||||||
"cli-table": "^0.3.6",
|
"cli-table": "^0.3.6",
|
||||||
"consola": "^2.15.0",
|
"consola": "^2.15.0",
|
||||||
"csv-stringify": "^5.6.5",
|
"csv-stringify": "^5.6.5",
|
||||||
|
"find": "0.3.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
|
"lodash.groupby": "4.6.0",
|
||||||
|
"lodash.uniqby": "4.7.0",
|
||||||
"prompts": "^2.4.1",
|
"prompts": "^2.4.1",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"valid-url": "^1.0.9"
|
"valid-url": "^1.0.9"
|
||||||
@@ -1051,9 +1057,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.14.5",
|
"version": "1.14.6",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz",
|
||||||
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==",
|
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2581,9 +2587,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/adapter": {
|
"@sasjs/adapter": {
|
||||||
"version": "2.12.0",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-2.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-3.3.1.tgz",
|
||||||
"integrity": "sha512-zzIuohhR8KUDl3DfIFOW38gv3LADPnOBCLOvLoKu4hH5R/UJDkjZ/Gdgc8B35vI7aOprYOLK/T5D/Z44OaTkqw==",
|
"integrity": "sha512-rmdOG+sjmwGipq1AHczwEXNUlzRFV5efj89neVVJWQMZR6JBC1O6Dr9HjEyJHPKcnQ6z3vzH9rRA2PGi5lgMhA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sasjs/utils": "^2.32.0",
|
"@sasjs/utils": "^2.32.0",
|
||||||
@@ -2595,15 +2601,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sasjs/cli": {
|
"@sasjs/cli": {
|
||||||
"version": "2.39.0",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-2.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/cli/-/cli-3.4.1.tgz",
|
||||||
"integrity": "sha512-n2LcU4n0QCEbUpXqZnBz/Ey5Td0nMJmgJpZRymMGfYEM0Y0x/CeXemd+kXHPjUvgQ+FX+SQzcvUQTEY/YlT4hA==",
|
"integrity": "sha512-voc0/h8bkRAqrj7Pu1egYfCOSFLlLrrh9bXVLuGvSvWK81MezRZnWciTHlQGc9BgO2wU+LrQ0baIMd6u/HMB5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sasjs/adapter": "2.12.0",
|
"@sasjs/adapter": "3.3.1",
|
||||||
"@sasjs/core": "2.45.2",
|
"@sasjs/core": "^3.8.0",
|
||||||
"@sasjs/lint": "1.11.2",
|
"@sasjs/lint": "1.11.2",
|
||||||
"@sasjs/utils": "2.32.0",
|
"@sasjs/utils": "2.34.1",
|
||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"csv-stringify": "5.6.5",
|
"csv-stringify": "5.6.5",
|
||||||
"dotenv": "10.0.0",
|
"dotenv": "10.0.0",
|
||||||
@@ -2624,10 +2630,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sasjs/core": {
|
"@sasjs/core": {
|
||||||
"version": "2.45.2",
|
"version": "3.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-2.45.2.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/core/-/core-3.8.1.tgz",
|
||||||
"integrity": "sha512-tg+oZCD8GFMXsg+vDL66LMnyU+t151Hrqd7yl+pMXH2qwkA14N/j6QdkTBZOchskqOA/3PnpOlAZN/xxMW2gdg==",
|
"integrity": "sha512-Yxak+WZwh8Z9IKcbi7aDDTRCcKlI6IUp7Ujavkec5pWMj3a2FSlLxu23lY2ERTBe7wMCGiaU7AseWlKcgd5joA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ts-loader": "^9.2.6"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"@sasjs/lint": {
|
"@sasjs/lint": {
|
||||||
"version": "1.11.2",
|
"version": "1.11.2",
|
||||||
@@ -2639,9 +2648,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sasjs/utils": {
|
"@sasjs/utils": {
|
||||||
"version": "2.32.0",
|
"version": "2.34.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.34.1.tgz",
|
||||||
"integrity": "sha512-xnvdEuI4PhTtulcdDEIMK7IxVj9bOMU1JTnxRuSEKWcsclY9P9Fw3cnMOOEgXCDffrOPn3f54DP7Wb1GXd+f8g==",
|
"integrity": "sha512-hd1qieH3d7+xH96n5DpRGTEazeAhYyBBKCdnKhOXMgF2TZVoHFdRs5REfT88CKza6DHBGRVGnIVm5ORGP4cVLg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/fs-extra": "^9.0.11",
|
"@types/fs-extra": "^9.0.11",
|
||||||
@@ -2650,8 +2659,11 @@
|
|||||||
"cli-table": "^0.3.6",
|
"cli-table": "^0.3.6",
|
||||||
"consola": "^2.15.0",
|
"consola": "^2.15.0",
|
||||||
"csv-stringify": "^5.6.5",
|
"csv-stringify": "^5.6.5",
|
||||||
|
"find": "0.3.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
|
"lodash.groupby": "4.6.0",
|
||||||
|
"lodash.uniqby": "4.7.0",
|
||||||
"prompts": "^2.4.1",
|
"prompts": "^2.4.1",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"valid-url": "^1.0.9"
|
"valid-url": "^1.0.9"
|
||||||
@@ -3421,9 +3433,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.14.5",
|
"version": "1.14.6",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz",
|
||||||
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==",
|
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"form-data": {
|
"form-data": {
|
||||||
|
|||||||
@@ -33,9 +33,9 @@
|
|||||||
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true"
|
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sasjs/cli": "^2.39.0"
|
"@sasjs/cli": "^3.4.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ts-loader": "^9.2.6"
|
"ts-loader": "^9.2.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,17 @@
|
|||||||
%ms_webout(CLOSE)
|
%ms_webout(CLOSE)
|
||||||
|
|
||||||
|
|
||||||
@param action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
@param [in] action Either FETCH, OPEN, ARR, OBJ or CLOSE
|
||||||
@param ds The dataset to send back to the frontend
|
@param [in] ds The dataset to send back to the frontend
|
||||||
@param dslabel= value to use instead of the real name for sending to JSON
|
@param [out] dslabel= value to use instead of table name for sending to JSON
|
||||||
@param fmt=(Y) Set to N to send back unformatted values
|
@param [in] fmt= (Y) Set to N to send back unformatted values
|
||||||
@param 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
|
||||||
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
|
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table,
|
||||||
|
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,
|
||||||
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
@@ -39,7 +45,9 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y);
|
%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y,missing=NULL
|
||||||
|
,showmeta=NO
|
||||||
|
);
|
||||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||||
sasjs_tables;
|
sasjs_tables;
|
||||||
|
|
||||||
@@ -91,7 +99,7 @@
|
|||||||
|
|
||||||
%else %if &action=ARR or &action=OBJ %then %do;
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||||
,engine=DATASTEP,dbg=%str(&_debug)
|
,engine=DATASTEP,missing=&missing,showmeta=&showmeta
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
@@ -112,9 +120,6 @@
|
|||||||
put ",""WORK"":{";
|
put ",""WORK"":{";
|
||||||
%do i=1 %to &wtcnt;
|
%do i=1 %to &wtcnt;
|
||||||
%let wt=&&wt&i;
|
%let wt=&&wt&i;
|
||||||
proc contents noprint data=&wt
|
|
||||||
out=_data_ (keep=name type length format:);
|
|
||||||
run;%let tempds=%scan(&syslast,2,.);
|
|
||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
dsid=open("WORK.&wt",'is');
|
dsid=open("WORK.&wt",'is');
|
||||||
nlobs=attrn(dsid,'NLOBS');
|
nlobs=attrn(dsid,'NLOBS');
|
||||||
@@ -124,8 +129,7 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES)
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP)
|
|
||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ data work.test;
|
|||||||
call symputx('dtval',dtval);
|
call symputx('dtval',dtval);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=Checking for error condition,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
%mp_assert(
|
%mp_assert(
|
||||||
iftrue=(&dtval=&compare),
|
iftrue=(&dtval=&compare),
|
||||||
52
tests/crossplatform/mp_jsonout.test.2.sas
Normal file
52
tests/crossplatform/mp_jsonout.test.2.sas
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_jsonout.sas macro with special missings
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_jsonout.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
filename webref temp;
|
||||||
|
|
||||||
|
data demo;
|
||||||
|
do x=._,.,.a,.b,.c,.d,.e,-99, 0, 1,2, 3.333333;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
%mp_jsonout(OPEN,jref=webref)
|
||||||
|
%mp_jsonout(OBJ,demo,jref=webref,fmt=N,missing=STRING)
|
||||||
|
%mp_jsonout(CLOSE,jref=webref)
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile webref;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
libname web JSON fileref=webref;
|
||||||
|
|
||||||
|
/* proc json turns to char - so switch back to numeric */
|
||||||
|
data work.test(keep=x);
|
||||||
|
set web.demo(rename=(x=y));
|
||||||
|
if y ='_' then x=._;
|
||||||
|
else if anyalpha(y) then x=input(cats(".",y),best.);
|
||||||
|
else x=input(y,best.);
|
||||||
|
put (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=Checking for error condition with special missing export,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
proc compare base=work.demo compare=work.test;
|
||||||
|
quit;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&sysinfo=0),
|
||||||
|
desc=Returned json is identical to input table for all special missings,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -6,12 +6,13 @@
|
|||||||
@li mp_lockanytable.sas
|
@li mp_lockanytable.sas
|
||||||
@li mp_assertcols.sas
|
@li mp_assertcols.sas
|
||||||
@li mp_assertcolvals.sas
|
@li mp_assertcolvals.sas
|
||||||
|
@li mp_coretable.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/* check create table */
|
/* check create table */
|
||||||
|
|
||||||
%mp_lockanytable(MAKETABLE, ctl_ds=work.controller)
|
%mp_coretable(LOCKTABLE,libds=work.controller)
|
||||||
|
|
||||||
%mp_assertcols(work.controller,
|
%mp_assertcols(work.controller,
|
||||||
cols=lock_status_cd lock_lib lock_ds lock_user_nm lock_ref lock_pid
|
cols=lock_status_cd lock_lib lock_ds lock_user_nm lock_ref lock_pid
|
||||||
|
|||||||
@@ -54,9 +54,9 @@
|
|||||||
that location
|
that location
|
||||||
@param [in] adapter= the macro uses the sasjs adapter by default. To use
|
@param [in] adapter= the macro uses the sasjs adapter by default. To use
|
||||||
another adapter, add a (different) fileref here.
|
another adapter, add a (different) fileref here.
|
||||||
@param [in] contextname= Choose a specific context on which to run the Job. Leave
|
@param [in] contextname= Choose a specific context on which to run the Job.
|
||||||
blank to use the default context. From Viya 3.5 it is possible to configure
|
Leave blank to use the default context. From Viya 3.5 it is possible to
|
||||||
a shared context - see
|
configure a shared context - see
|
||||||
https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
|
https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
|
||||||
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
|
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
@@ -237,9 +237,15 @@ data _null_;
|
|||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=DATASTEP,dbg=0 ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
|
||||||
|
put ' ,engine=DATASTEP ';
|
||||||
|
put ' ,dbg=0 /* DEPRECATED */ ';
|
||||||
|
put ' ,missing=NULL ';
|
||||||
|
put ' ,showmeta=NO ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%put output location=&jref; ';
|
put '%local tempds colinfo fmtds i numcols; ';
|
||||||
|
put '%let numcols=0; ';
|
||||||
|
put ' ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
put ' options nobomfile; ';
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
||||||
@@ -248,118 +254,124 @@ data _null_;
|
|||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if (&action=ARR or &action=OBJ) %then %do; ';
|
put '%else %if (&action=ARR or &action=OBJ) %then %do; ';
|
||||||
put ' options validvarname=upcase; ';
|
put ' options validvarname=upcase; ';
|
||||||
put ' data _null_;file &jref mod encoding=''utf-8'' ; ';
|
put ' data _null_; file &jref encoding=''utf-8'' mod; ';
|
||||||
put ' put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":"; ';
|
put ' put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":"; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
|
put ' /* grab col defs */ ';
|
||||||
|
put ' proc contents noprint data=&ds ';
|
||||||
|
put ' out=_data_(keep=name type length format formatl formatd varnum label); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' %let colinfo=%scan(&syslast,2,.); ';
|
||||||
|
put ' proc sort data=&colinfo; ';
|
||||||
|
put ' by varnum; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' /* move meta to mac vars */ ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
|
||||||
|
put ' set &colinfo end=last nobs=nobs; ';
|
||||||
|
put ' name=upcase(name); ';
|
||||||
|
put ' /* fix formats */ ';
|
||||||
|
put ' if type=2 or type=6 then do; ';
|
||||||
|
put ' typelong=''char''; ';
|
||||||
|
put ' length fmt $49.; ';
|
||||||
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' newlen=max(formatl,length); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' else do; ';
|
||||||
|
put ' typelong=''num''; ';
|
||||||
|
put ' if format='''' then fmt=''best.''; ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
|
put ' /* needs to be wide, for datetimes etc */ ';
|
||||||
|
put ' newlen=max(length,formatl,24); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' /* 32 char unique name */ ';
|
||||||
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
|
put ' ';
|
||||||
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
|
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||||
|
put ' call symputx(cats(''length'',_n_),length,''l''); ';
|
||||||
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
|
put ' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
|
||||||
|
put ' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
|
put ' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
|
||||||
|
put ' ';
|
||||||
put ' %if &engine=PROCJSON %then %do; ';
|
put ' %if &engine=PROCJSON %then %do; ';
|
||||||
put ' data;run;%let tempds=&syslast; ';
|
put ' %if &missing=STRING %then %do; ';
|
||||||
put ' proc sql;drop table &tempds; ';
|
put ' %put &sysmacroname: Special Missings not supported in proc json.; ';
|
||||||
|
put ' %put &sysmacroname: Switching to DATASTEP engine; ';
|
||||||
|
put ' %goto datastep; ';
|
||||||
|
put ' %end; ';
|
||||||
put ' data &tempds /view=&tempds;set &ds; ';
|
put ' data &tempds /view=&tempds;set &ds; ';
|
||||||
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 ' proc json out=&jref pretty ';
|
put ' proc json out=&jref pretty ';
|
||||||
put ' %if &action=ARR %then nokeys ; ';
|
put ' %if &action=ARR %then nokeys ; ';
|
||||||
put ' ;export &tempds / nosastags fmtnumeric; ';
|
put ' ;export &tempds / nosastags fmtnumeric; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' proc sql;drop view &tempds; ';
|
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %else %if &engine=DATASTEP %then %do; ';
|
put ' %else %if &engine=DATASTEP %then %do; ';
|
||||||
put ' %local cols i tempds; ';
|
put ' %datastep: ';
|
||||||
put ' %let cols=0; ';
|
put ' %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 ';
|
||||||
put ' %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 %then %do; ';
|
put ' %then %do; ';
|
||||||
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
||||||
put ' %return; ';
|
put ' %return; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &fmt=Y %then %do; ';
|
|
||||||
put ' %put converting every variable to a formatted variable; ';
|
|
||||||
put ' /* see mp_ds2fmtds.sas for source */ ';
|
|
||||||
put ' proc contents noprint data=&ds ';
|
|
||||||
put ' out=_data_(keep=name type length format formatl formatd varnum); ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' proc sort; ';
|
|
||||||
put ' by varnum; ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' %local fmtds; ';
|
|
||||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
|
||||||
put ' /* prepare formats and varnames */ ';
|
|
||||||
put ' data _null_; ';
|
|
||||||
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
|
||||||
put ' set &fmtds end=last nobs=nobs; ';
|
|
||||||
put ' name=upcase(name); ';
|
|
||||||
put ' /* fix formats */ ';
|
|
||||||
put ' if type=2 or type=6 then do; ';
|
|
||||||
put ' length fmt $49.; ';
|
|
||||||
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
|
||||||
put ' else fmt=cats(format,formatl,''.''); ';
|
|
||||||
put ' newlen=max(formatl,length); ';
|
|
||||||
put ' end; ';
|
|
||||||
put ' else do; ';
|
|
||||||
put ' if format='''' then fmt=''best.''; ';
|
|
||||||
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
|
||||||
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
|
||||||
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
|
||||||
put ' /* needs to be wide, for datetimes etc */ ';
|
|
||||||
put ' newlen=max(length,formatl,24); ';
|
|
||||||
put ' end; ';
|
|
||||||
put ' /* 32 char unique name */ ';
|
|
||||||
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
put ' data _data_; ';
|
||||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
|
||||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' data &fmtds; ';
|
|
||||||
put ' /* rename on entry */ ';
|
put ' /* rename on entry */ ';
|
||||||
put ' set &ds(rename=( ';
|
put ' set &ds(rename=( ';
|
||||||
put ' %local i; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %do i=1 %to &nobs; ';
|
|
||||||
put ' &&name&i=&&newname&i ';
|
put ' &&name&i=&&newname&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' )); ';
|
put ' )); ';
|
||||||
put ' %do i=1 %to &nobs; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' length &&name&i $&&len&i; ';
|
put ' length &&name&i $&&len&i; ';
|
||||||
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
||||||
put ' drop &&newname&i; ';
|
put ' drop &&newname&i; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' if _error_ then call symputx(''syscc'',1012); ';
|
put ' if _error_ then call symputx(''syscc'',1012); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %let ds=&fmtds; ';
|
put ' %let fmtds=&syslast; ';
|
||||||
put ' %end; /* &fmt=Y */ ';
|
put ' %end; ';
|
||||||
put ' data _null_;file &jref mod encoding=''utf-8'' ; ';
|
|
||||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
|
||||||
put ' proc sort ';
|
|
||||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
|
||||||
put ' out=_data_; ';
|
|
||||||
put ' by varnum; ';
|
|
||||||
put ' ';
|
|
||||||
put ' data _null_; ';
|
|
||||||
put ' set _last_ end=last; ';
|
|
||||||
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
|
||||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
|
||||||
put ' call symputx(cats(''len'',_n_),length,''l''); ';
|
|
||||||
put ' if last then call symputx(''cols'',_n_,''l''); ';
|
|
||||||
put ' run; ';
|
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' proc format; /* credit yabwon for special null removal */ ';
|
put ' proc format; /* credit yabwon for special null removal */ ';
|
||||||
put ' value bart ._ - .z = null ';
|
put ' value bart (default=40) ';
|
||||||
|
put ' %if &missing=NULL %then %do; ';
|
||||||
|
put ' ._ - .z = null ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' %else %do; ';
|
||||||
|
put ' ._ = [quote()] ';
|
||||||
|
put ' . = null ';
|
||||||
|
put ' .a - .z = [quote()] ';
|
||||||
|
put ' %end; ';
|
||||||
put ' other = [best.]; ';
|
put ' other = [best.]; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' data;run; %let tempds=&syslast; /* temp table for spesh char management */ ';
|
|
||||||
put ' proc sql; drop table &tempds; ';
|
|
||||||
put ' data &tempds/view=&tempds; ';
|
put ' data &tempds/view=&tempds; ';
|
||||||
put ' attrib _all_ label=''''; ';
|
put ' attrib _all_ label=''''; ';
|
||||||
put ' %do i=1 %to &cols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&type&i=char %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' length &&name&i $32767; ';
|
put ' length &&name&i $32767; ';
|
||||||
put ' format &&name&i $32767.; ';
|
put ' format &&name&i $32767.; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' set &ds; ';
|
put ' %if &fmt=Y %then %do; ';
|
||||||
|
put ' set &fmtds; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' %else %do; ';
|
||||||
|
put ' set &ds; ';
|
||||||
|
put ' %end; ';
|
||||||
put ' format _numeric_ bart.; ';
|
put ' format _numeric_ bart.; ';
|
||||||
put ' %do i=1 %to &cols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &&type&i=char %then %do; ';
|
put ' %if &&typelong&i=char or &fmt=Y %then %do; ';
|
||||||
put ' &&name&i=''"''!!trim(prxchange(''s/"/\"/'',-1, ';
|
put ' &&name&i=''"''!!trim(prxchange(''s/"/\"/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
||||||
@@ -369,49 +381,72 @@ data _null_;
|
|||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
|
put ' ';
|
||||||
put ' /* write to temp loc to avoid _webout truncation ';
|
put ' /* write to temp loc to avoid _webout truncation ';
|
||||||
put ' - https://support.sas.com/kb/49/325.html */ ';
|
put ' - https://support.sas.com/kb/49/325.html */ ';
|
||||||
put ' filename _sjs temp lrecl=131068 encoding=''utf-8''; ';
|
put ' filename _sjs temp lrecl=131068 encoding=''utf-8''; ';
|
||||||
put ' data _null_; file _sjs lrecl=131068 encoding=''utf-8'' mod ; ';
|
put ' data _null_; file _sjs lrecl=131068 encoding=''utf-8'' mod ; ';
|
||||||
|
put ' if _n_=1 then put "["; ';
|
||||||
put ' set &tempds; ';
|
put ' set &tempds; ';
|
||||||
put ' if _n_>1 then put "," @; put ';
|
put ' if _n_>1 then put "," @; put ';
|
||||||
put ' %if &action=ARR %then "[" ; %else "{" ; ';
|
put ' %if &action=ARR %then "[" ; %else "{" ; ';
|
||||||
put ' %do i=1 %to &cols; ';
|
put ' %do i=1 %to &numcols; ';
|
||||||
put ' %if &i>1 %then "," ; ';
|
put ' %if &i>1 %then "," ; ';
|
||||||
put ' %if &action=OBJ %then """&&name&i"":" ; ';
|
put ' %if &action=OBJ %then """&&name&i"":" ; ';
|
||||||
put ' &&name&i ';
|
put ' &&name&i ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if &action=ARR %then "]" ; %else "}" ; ; ';
|
put ' %if &action=ARR %then "]" ; %else "}" ; ; ';
|
||||||
put ' proc sql; ';
|
|
||||||
put ' drop view &tempds; ';
|
|
||||||
put ' /* now write the long strings to _webout 1 byte at a time */ ';
|
put ' /* now write the long strings to _webout 1 byte at a time */ ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' length filein 8 fileid 8; ';
|
put ' length filein 8 fileid 8; ';
|
||||||
put ' filein = fopen("_sjs",''I'',1,''B''); ';
|
put ' filein=fopen("_sjs",''I'',1,''B''); ';
|
||||||
put ' fileid = fopen("&jref",''A'',1,''B''); ';
|
put ' fileid=fopen("&jref",''A'',1,''B''); ';
|
||||||
put ' rec = ''20''x; ';
|
put ' rec=''20''x; ';
|
||||||
put ' do while(fread(filein)=0); ';
|
put ' do while(fread(filein)=0); ';
|
||||||
put ' rc = fget(filein,rec,1); ';
|
put ' rc=fget(filein,rec,1); ';
|
||||||
put ' rc = fput(fileid, rec); ';
|
put ' rc=fput(fileid, rec); ';
|
||||||
put ' rc =fwrite(fileid); ';
|
put ' rc=fwrite(fileid); ';
|
||||||
put ' end; ';
|
put ' end; ';
|
||||||
put ' rc = fclose(filein); ';
|
put ' /* close out the table */ ';
|
||||||
put ' rc = fclose(fileid); ';
|
put ' rc=fput(fileid, "]"); ';
|
||||||
|
put ' rc=fwrite(fileid); ';
|
||||||
|
put ' rc=fclose(filein); ';
|
||||||
|
put ' rc=fclose(fileid); ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' filename _sjs clear; ';
|
put ' filename _sjs clear; ';
|
||||||
put ' data _null_; file &jref mod encoding=''utf-8'' ; ';
|
put ' %end; ';
|
||||||
put ' put "]"; ';
|
put ' ';
|
||||||
|
put ' proc sql; ';
|
||||||
|
put ' drop view &tempds; ';
|
||||||
|
put ' drop table &colinfo; ';
|
||||||
|
put ' ';
|
||||||
|
put ' %if &showmeta=YES %then %do; ';
|
||||||
|
put ' data _null_; file &jref encoding=''utf-8'' mod; ';
|
||||||
|
put ' put ", ""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":{""vars"":{"; ';
|
||||||
|
put ' do i=1 to &numcols; ';
|
||||||
|
put ' name=quote(trim(symget(cats(''name'',i)))); ';
|
||||||
|
put ' format=quote(trim(symget(cats(''fmt'',i)))); ';
|
||||||
|
put ' label=quote(trim(symget(cats(''label'',i)))); ';
|
||||||
|
put ' length=quote(trim(symget(cats(''length'',i)))); ';
|
||||||
|
put ' type=quote(trim(symget(cats(''typelong'',i)))); ';
|
||||||
|
put ' if i>1 then put "," @@; ';
|
||||||
|
put ' put name '':{"format":'' format '',"label":'' label ';
|
||||||
|
put ' '',"length":'' length '',"type":'' type ''}''; ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' put ''}}''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' mod ; ';
|
put ' data _null_; file &jref encoding=''utf-8'' mod ; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%mend mp_jsonout; ';
|
put '%mend mp_jsonout; ';
|
||||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y); ';
|
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL ';
|
||||||
|
put ' ,showmeta=NO ';
|
||||||
|
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; ';
|
||||||
put '%if %index("&_debug",log) %then %let _debug=131; ';
|
put '%if %index("&_debug",log) %then %let _debug=131; ';
|
||||||
@@ -533,12 +568,13 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put ' /* setup json */ ';
|
put ' /* setup json */ ';
|
||||||
put ' data _null_;file &fref; ';
|
put ' data _null_;file &fref; ';
|
||||||
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; ';
|
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||||
|
put ' put '',"SYSTIME" : "'' "&SYSTIME" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt ';
|
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt ';
|
||||||
put ' ,jref=&fref,engine=DATASTEP,dbg=%str(&_debug) ';
|
put ' ,jref=&fref,engine=DATASTEP,missing=&missing,showmeta=&showmeta ';
|
||||||
put ' ) ';
|
put ' ) ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%else %if &action=CLOSE %then %do; ';
|
put '%else %if &action=CLOSE %then %do; ';
|
||||||
@@ -558,9 +594,6 @@ data _null_;
|
|||||||
put ' data _null_; file &fref mod; put ",""WORK"":{"; ';
|
put ' data _null_; file &fref mod; put ",""WORK"":{"; ';
|
||||||
put ' %do i=1 %to &wtcnt; ';
|
put ' %do i=1 %to &wtcnt; ';
|
||||||
put ' %let wt=&&wt&i; ';
|
put ' %let wt=&&wt&i; ';
|
||||||
put ' proc contents noprint data=&wt ';
|
|
||||||
put ' out=_data_ (keep=name type length format:); ';
|
|
||||||
put ' run;%let tempds=%scan(&syslast,2,.); ';
|
|
||||||
put ' data _null_; file &fref mod; ';
|
put ' data _null_; file &fref mod; ';
|
||||||
put ' dsid=open("WORK.&wt",''is''); ';
|
put ' dsid=open("WORK.&wt",''is''); ';
|
||||||
put ' nlobs=attrn(dsid,''NLOBS''); ';
|
put ' nlobs=attrn(dsid,''NLOBS''); ';
|
||||||
@@ -570,8 +603,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,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP) ';
|
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES) ';
|
||||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP) ';
|
|
||||||
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; ';
|
||||||
@@ -596,6 +628,9 @@ data _null_;
|
|||||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||||
|
put ' memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)"; ';
|
||||||
|
put ' memsize=quote(cats(memsize)); ';
|
||||||
|
put ' put '',"MEMSIZE" : '' memsize; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||||
@@ -629,8 +664,10 @@ data _null_;
|
|||||||
put '%global __program _program;';
|
put '%global __program _program;';
|
||||||
put '%let _program=%sysfunc(coalescec(&__program,&_program));';
|
put '%let _program=%sysfunc(coalescec(&__program,&_program));';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro webout(action,ds,dslabel=,fmt=);';
|
put '%macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);';
|
||||||
put ' %mv_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt)';
|
put ' %mv_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing';
|
||||||
|
put ' ,showmeta=&showmeta';
|
||||||
|
put ' )';
|
||||||
put '%mend;';
|
put '%mend;';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,19 @@
|
|||||||
%mv_webout(CLOSE)
|
%mv_webout(CLOSE)
|
||||||
|
|
||||||
|
|
||||||
@param action Either OPEN, ARR, OBJ or CLOSE
|
@param [in] action Either OPEN, ARR, OBJ or CLOSE
|
||||||
@param ds The dataset to send back to the frontend
|
@param [in] ds The dataset to send back to the frontend
|
||||||
@param _webout= fileref for returning the json
|
@param [in] _webout= fileref for returning the json
|
||||||
@param fref=(_mvwtemp) Temp fileref to which to write the output
|
@param [out] fref=(_mvwtemp) Temp fileref to which to write the output
|
||||||
@param dslabel= value to use instead of the real name for sending to JSON
|
@param [out] dslabel= value to use instead of table name for sending to JSON
|
||||||
@param fmt=(Y) change to N to strip formats from output
|
@param [in] fmt=(Y) change to N to strip formats from output
|
||||||
@param 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
|
||||||
|
(eg `null`) or as STRING values (eg `".a"` or `".b"`)
|
||||||
|
@param [in] showmeta= (NO) Set to YES to output metadata alongside each table,
|
||||||
|
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,
|
||||||
|
`,"$tablename":{"formats":{"col1":"$CHAR1"},"types":{"COL1":"C"}}`
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_jsonout.sas
|
@li mp_jsonout.sas
|
||||||
@@ -36,7 +42,9 @@
|
|||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
|
|
||||||
**/
|
**/
|
||||||
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y);
|
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL
|
||||||
|
,showmeta=NO
|
||||||
|
);
|
||||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||||
sasjs_tables SYS_JES_JOB_URI;
|
sasjs_tables SYS_JES_JOB_URI;
|
||||||
%if %index("&_debug",log) %then %let _debug=131;
|
%if %index("&_debug",log) %then %let _debug=131;
|
||||||
@@ -158,12 +166,13 @@
|
|||||||
|
|
||||||
/* setup json */
|
/* setup json */
|
||||||
data _null_;file &fref;
|
data _null_;file &fref;
|
||||||
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||||
|
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=ARR or &action=OBJ %then %do;
|
%else %if &action=ARR or &action=OBJ %then %do;
|
||||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt
|
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt
|
||||||
,jref=&fref,engine=DATASTEP,dbg=%str(&_debug)
|
,jref=&fref,engine=DATASTEP,missing=&missing,showmeta=&showmeta
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%else %if &action=CLOSE %then %do;
|
%else %if &action=CLOSE %then %do;
|
||||||
@@ -183,9 +192,6 @@
|
|||||||
data _null_; file &fref mod; put ",""WORK"":{";
|
data _null_; file &fref mod; put ",""WORK"":{";
|
||||||
%do i=1 %to &wtcnt;
|
%do i=1 %to &wtcnt;
|
||||||
%let wt=&&wt&i;
|
%let wt=&&wt&i;
|
||||||
proc contents noprint data=&wt
|
|
||||||
out=_data_ (keep=name type length format:);
|
|
||||||
run;%let tempds=%scan(&syslast,2,.);
|
|
||||||
data _null_; file &fref mod;
|
data _null_; file &fref mod;
|
||||||
dsid=open("WORK.&wt",'is');
|
dsid=open("WORK.&wt",'is');
|
||||||
nlobs=attrn(dsid,'NLOBS');
|
nlobs=attrn(dsid,'NLOBS');
|
||||||
@@ -195,8 +201,7 @@
|
|||||||
put " ""&wt"" : {";
|
put " ""&wt"" : {";
|
||||||
put '"nlobs":' nlobs;
|
put '"nlobs":' nlobs;
|
||||||
put ',"nvars":' nvars;
|
put ',"nvars":' nvars;
|
||||||
%mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP)
|
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=YES)
|
||||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP)
|
|
||||||
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;
|
||||||
@@ -221,6 +226,9 @@
|
|||||||
put ',"SYSVLONG" : ' sysvlong;
|
put ',"SYSVLONG" : ' sysvlong;
|
||||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||||
|
memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)";
|
||||||
|
memsize=quote(cats(memsize));
|
||||||
|
put ',"MEMSIZE" : ' memsize;
|
||||||
put "}";
|
put "}";
|
||||||
|
|
||||||
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
||||||
|
|||||||
Reference in New Issue
Block a user