Loading...
Searching...
No Matches
viewdata.sas
Go to the documentation of this file.
1/**
2 @file viewdata.sas
3 @brief Provide the raw view of the data
4 @details Pass a LIBDS and FILTER_RK to return a dataset for viewing.
5 VIEW datasets include all columns / rows (unlike EDIT, which are filtered
6 for current records and don't include the SCD2 etc cols).
7
8 <h4> Service Inputs </h4>
9
10 <h5> SASCONTROLTABLE </h5>
11 |LIBDS:$41.|FILTER_RK:$5.|SEARCHTYPE:$4|SEARCHVAL:$1000
12 |---|---|---|---
13 |DC258467.MPE_X_TEST|-1|CHAR|Some String|
14
15 <h4> Service Outputs </h4>
16
17 <h5> cols </h5>
18 @li DDTYPE - C=CHARACTER, N=NUMERIC, else DATE / TIME / DATETIME
19 @li FORMAT
20 @li LABEL
21 @li LENGTH
22 @li NAME
23 @li TYPE
24
25 <h5> sasparams </h5>
26 @li FILTER_TEXT
27 @li NOBS
28 @li PK_FIELDS - string seperated list of primary key fields, if they exist
29 @li TABLENAME
30 @li TABLEURI
31 @li VARS
32
33 <h5> versions </h5>
34 history of DC versions for this particular table
35
36 <h5> viewdata </h5>
37 The raw data from the target table.
38
39 <h4> SAS Macros </h4>
40 @li dc_assignlib.sas
41 @li dc_casload.sas
42 @li dc_createdataset.sas
43 @li dc_gettableid.sas
44 @li mf_existds.sas
45 @li mf_getvarcount.sas
46 @li mf_nobs.sas
47 @li mf_verifymacvars.sas
48 @li mp_abort.sas
49 @li mp_cntlout.sas
50 @li mp_getcols.sas
51 @li mp_getpk.sas
52 @li mp_jsonout.sas
53 @li mp_searchdata.sas
54 @li mp_validatecol.sas
55 @li mpe_columnlevelsecurity.sas
56 @li mpe_dsmeta.sas
57 @li mpe_getversions.sas
58 @li mpe_filtermaster.sas
59
60
61 @version 9.2
62 @author 4GL Apps Ltd
63 @copyright 4GL Apps Ltd. This code may only be used within Data Controller
64 and may not be re-distributed or re-sold without the express permission of
65 4GL Apps Ltd.
66**/
67
68%mpeinit()
69
70/* configure macvars */
71%global LIBDS FILTER_RK SEARCHVAL SEARCHTYPE FMT_IND;
72
73/* avoid code injection */
74%let FMT_IND=0;
75%let SEARCHTYPE=;
76%let SEARCHVAL=;
77%let FILTER_RK=;
78%let LIBDS=;
79
80/**
81 * Validate inputs
82 */
83data work.intest;
84 length libds $41 filter_rk 8. searchval $100 searchtype $4;
85 set work.SASCONTROLTABLE;
86 call symputx('orig_libds',libds);
87 /* validate filter_rk */
88 if filter_rk le 0 then filter_rk=-1;
89
90 /* check if the request is for a format catalog */
91 if substr(cats(reverse(libds)),1,3)=:'CF-' then do;
92 libds=scan(libds,1,'-');
93 putlog "Format Catalog Captured";
94 call symputx('fmt_ind',1);
95 end;
96 putlog (_all_)(=);
97
98 /* validate libds */
99 %mp_validatecol(LIBDS,LIBDS,is_libds)
100
101 if searchtype in ('CHAR','NUM') then do;
102 searchval=tranwrd(searchval,'%','');
103 searchval=tranwrd(searchval,'&','');
104 searchval=tranwrd(searchval,';','');
105 searchval=tranwrd(searchval,'"','');
106 call symputx('searchtype',searchtype);
107 call symputx('searchval',searchval);
108 end;
109 else if searchtype not in ('','NONE') then do;
110 putlog 'ERR' 'OR: Invalid searchtype:' searchtype;
111 stop;
112 end;
113
114 if is_libds=0 then do;
115 putlog 'ERR' 'OR: Invalid libds:' libds;
116 stop;
117 end;
118 else do;
119 call symputx('filter_rk',filter_rk);
120 call symputx('libds',libds);
121 end;
122 output;
123 stop;
124run;
125
126%mp_abort(iftrue= (%mf_verifymacvars(libds filter_rk fmt_ind)=0)
127 ,mac=&_program..sas
128 ,msg=%str(Problem with macro inputs)
129)
130
131%mp_abort(iftrue= (%mf_nobs(work.intest)=0)
132 ,mac=&_program
133 ,msg=%str(Some err with service inputs)
134)
135%mp_abort(iftrue= (&syscc ne 0)
136 ,mac=&_program..sas
137 ,msg=%str(syscc=&syscc)
138)
139
140
141/**
142 * assign the Library
143 */
144%dc_assignlib(READ,%scan(&LIBDS,1,.))
145%dc_casload(&libds)
146
147/* abort if looking for a format and the catalog doesn't exist */
148%mp_abort(iftrue= (&fmt_ind=1 and %sysfunc(exist(&libds,CATALOG))=0)
149 ,mac=&_program..sas
150 ,msg=%str(Catalog &libds does not exist!)
151)
152
153/**
154 check if dataset can actually be opened - as library may exist but it may not
155 be possible to assign, and even if it can, the physical table may not exist
156**/
157data _null_;
158 if &fmt_ind=0 then do;
159 dsid=open("&libds");
160 rc=close(dsid);
161 end;
162 else dsid=42;
163 call symputx('existds',dsid,'l');
164 putlog 'dataset exists check:' dsid;
165run;
166
167/**
168 * get the data
169 */
170%global dsobs;
171%let dsobs=0;
172%macro x();
173%if not %symexist(DC_MAXOBS_WEBVIEW) %then %do;
174 %put NOTE:;%put NOTE- DC_MAXOBS_WEBVIEW not found!;
175 %put NOTE- Please add to &mpelib..MPE_CONFIG table;
176 %put NOTE-;%put NOTE-;
177 %global DC_MAXOBS_WEBVIEW;
178 %let DC_MAXOBS_WEBVIEW=500;
179%end;
180%if &existds>0 %then %do;
181
182 %if &fmt_ind=1 %then %do;
183 /* export format and point the libds to the output table from here on */
184 %mp_cntlout(
185 libcat=&libds
186 ,fmtlist=0
187 ,cntlout=work.fmtextract
188 )
189 %let libds=WORK.FMTEXTRACT;
190 proc datasets lib=work noprint;
191 modify FMTEXTRACT;
192 index create
193 pk_cntlout=(type fmtname fmtrow)
194 /nomiss unique;
195 quit;
196 %end;
197
198 proc sql noprint;
199 select count(*) into: dsobs from &libds;
200
201 %put preparing query;
202 %mpe_filtermaster(VIEW,&libds,
203 dclib=&mpelib,
204 filter_rk=&filter_rk,
205 outref=filtref,
206 outds=work.query
207 )
208 %put printing generated filterquery:;
209 data _null_;
210 infile filtref;
211 input;
212 putlog _infile_;
213 run;
214
215 %if &searchtype=NONE or "%trim(&searchtype) " = " " %then %do;
216 /* get row count */
217 filename rows temp;
218 data _null_;
219 file rows;
220 infile filtref end=eof;
221 input;
222 if _n_=1 then do;
223 put 'proc sql;';
224 put "select count(*) into: dsobs from &libds where";
225 end;
226 put _infile_;
227 if eof then put ';';
228 run;
229 data _null_;
230 infile rows;
231 input;
232 putlog _infile_;
233 run;
234
235 %inc rows;
236
237 /* send actual data, filtered and row-capped */
238 data work.viewdata;
239 set &libds;
240 where %inc filtref;;
241 if _n_>&DC_MAXOBS_WEBVIEW then stop;
242 run;
243 %if %mf_nobs(work.viewdata)=0 %then %do;
244 data work.viewdata;
245 /* send empty row if empty table to help with hot rendering */
246 output;
247 set work.viewdata;
248 run;
249 %end;
250 %end;
251 %else %do;
252 data work.vwsearch/view=work.vwsearch;
253 set &libds;
254 where %inc filtref;;
255 run;
256 %if %upcase(&searchtype)=CHAR %then %do;
257 %mp_searchdata(lib=work
258 ,ds=vwsearch
259 ,string=%superq(searchval)
260 ,outobs=&DC_MAXOBS_WEBVIEW
261 )
262 %end;
263 %else %if %upcase(&searchtype)=NUM %then %do;
264 %mp_searchdata(lib=work
265 ,ds=vwsearch
266 ,numval=%superq(searchval)
267 ,outobs=&DC_MAXOBS_WEBVIEW
268 )
269 %end;
270 %if %mf_existds(libds=MPSEARCH.vwsearch) %then %do;
271 %let dsobs=%mf_nobs(MPSEARCH.vwsearch);
272 data viewdata;
273 set MPSEARCH.vwsearch;
274 if _n_<&DC_MAXOBS_WEBVIEW;
275 run;
276 %end;
277 %else %do;
278 %let dsobs=0;
279 data viewdata;
280 set &libds;
281 stop;
282 run;
283 %end;
284 %end;
285%end;
286%else %do;
287 /* physical table is not accessible so create from metatadata definition */
288 %dc_createdataset(libds=&libds,outds=viewdata)
289 data viewData;
290 output;
291 set viewdata;
292 run;
293
294 /* make filtref / work.query / work.groups to avoid downstream issues */
295 filename filtref temp;
296 data work.query;
297 file filtref;
298 x=0;
299 put x;
300 run;
301 data work.groups;
302 length groupuri groupname $32 groupdesc $128 ;
303 call missing (of _all_);
304 output;
305 stop;
306 run;
307%end;
308%mend x; %x()
309
310/* apply column level security */
311%mpe_columnlevelsecurity(%scan(&libds,1,.),%scan(&libds,2,.),work.viewdata
312 ,mode=VIEW
313 ,clsds=&mpelib..mpe_column_level_security
314 ,groupds=work.groups /* was created in mpe_filtermaster */
315 ,outds=work.viewdata2
316 ,outmeta=work.cls_rules
317)
318
319
320/* get table uri (if sas 9) to enable linking direct to lineage */
321%dc_gettableid(libref=%scan(&libds,1,.)
322 ,ds=%scan(&libds,2,.)
323 ,outds=work.parambase
324)
325
326data _null_;
327 infile filtref end=eof;
328 input;
329 length filter_text $32767;
330 retain filter_text;
331 filter_text=catx(' ',filter_text,_infile_);
332 if eof then do;
333 if cats(filter_text)='1=1' then filter_text='';
334 call symputx('filter_text',filter_text);
335 end;
336run;
337
338%mp_getpk(%scan(&libds,1,.), ds=%scan(&libds,2,.), outds=work.pk_fields)
339
340%let pk_fields=;
341data _null_;
342 set work.pk_fields;
343 call symputx('pk_fields',pk_fields);
344run;
345
346data work.sasparams;
347 set work.parambase;
348 format FILTER_TEXT $32767.;
349 FILTER_TEXT=symget('FILTER_TEXT');
350 length PK_FIELDS $512;
351 PK_FIELDS=symget('PK_FIELDS');
352 nobs=&dsobs;
353 vars=%mf_getvarcount(viewdata);
354 maxrows=&DC_MAXOBS_WEBVIEW;
355run;
356
357%mp_abort(iftrue= (&syscc ne 0)
358 ,mac=&_program..sas
359 ,msg=%str(syscc=&syscc)
360)
361
362%mp_getcols(&libds, outds=cols1)
363
364/* trim COLS payload in the SQL below - DDTYPE C=CHARACTER N=NUMERIC
365 (dates kept in full), VARNUM dropped (client relies on column order,
366 not position) */
367proc sql;
368create table cols as
369 select a.name
370 ,a.type
371 ,a.length
372 ,a.format
373 ,a.fmtname
374 ,case a.ddtype
375 when 'CHARACTER' then 'C'
376 when 'NUMERIC' then 'N'
377 else a.ddtype end as ddtype
378 ,coalesce(b.dd_shortdesc,a.label,a.name) as label
379 from cols1 a
380 left join &mpelib..mpe_datadictionary
381 (where=(&dc_dttmtfmt. < tx_to
382 and dd_source ? %upcase("&orig_libds")
383 and dd_type='COLUMN')) b
384 on scan(b.dd_source,-1,'.')=upcase(a.name);
385quit;
386
387
388%mpe_dsmeta(&orig_libds, outds=dsmeta)
389
390%mpe_getversions(&mpelib,
391 %scan(&orig_libds,1,.),
392 %scan(&orig_libds,2,.),
393 outds=versions
394)
395
396%webout(OPEN)
397%webout(OBJ,cls_rules)
398%webout(OBJ,cols)
399%webout(OBJ,dsmeta)
400%webout(OBJ,query)
401%webout(OBJ,sasparams)
402%webout(OBJ,versions)
403%webout(OBJ,viewData2,fmt=Y,missing=STRING,showmeta=YES,dslabel=viewdata)
404%webout(CLOSE)
405
406%mpeterm()