1
0
mirror of https://github.com/sasjs/core.git synced 2026-01-07 09:30:06 +00:00

feat: adding fileref support for mp_dirlist, as well as a directory column on the output dataset

This commit is contained in:
2020-10-29 11:30:15 +01:00
parent 6b782a4fa2
commit 6f06e5540d
2 changed files with 66 additions and 41 deletions

59
all.sas
View File

@@ -380,7 +380,7 @@ options noquotelenmax;
@brief Returns the engine type of a SAS library @brief Returns the engine type of a SAS library
@details Usage: @details Usage:
%put %mf_getEngine(SASHELP); %put %mf_getengine(SASHELP);
returns: returns:
> V9 > V9
@@ -398,9 +398,10 @@ options noquotelenmax;
@version 9.2 @version 9.2
@author Allan Bowe @author Allan Bowe
**/
%macro mf_getEngine(libref **/ /** \cond */
%macro mf_getengine(libref
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local dsid engnum rc engine; %local dsid engnum rc engine;
@@ -419,7 +420,8 @@ options noquotelenmax;
&engine &engine
%mend; %mend;
/**
/** \endcond *//**
@file @file
@brief Returns the size of a file in bytes. @brief Returns the size of a file in bytes.
@details Provide full path/filename.extension to the file, eg: @details Provide full path/filename.extension to the file, eg:
@@ -1955,17 +1957,17 @@ run;
%mend;/** %mend;/**
@file @file
@brief Returns all files and subdirectories within a specified parent @brief Returns all files and subdirectories within a specified parent
@details When used with getattrs=NO, is not OS specific (uses dopen / dread). @details When used with getattrs=NO, is not OS specific (uses dopen / dread).
If getattrs=YES then the doptname / foptname functions are used to scan all If getattrs=YES then the doptname / foptname functions are used to scan all
properties - any characters that are not valid in a SAS name (v7) are simply properties - any characters that are not valid in a SAS name (v7) are simply
stripped, and the table is transposed so theat each property is a column stripped, and the table is transposed so theat each property is a column
and there is one file per row. An attempt is made to get all properties and there is one file per row. An attempt is made to get all properties
whether a file or folder, but some files/folders cannot be accessed, and so whether a file or folder, but some files/folders cannot be accessed, and so
not all properties can / will be populated. not all properties can / will be populated.
Credit for the rename approach: Credit for the rename approach:
https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375/highlight/true#M5003 https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375/highlight/true#M5003
usage: usage:
@@ -1974,21 +1976,25 @@ run;
%mp_dirlist(outds=cwdfileprops, getattrs=YES) %mp_dirlist(outds=cwdfileprops, getattrs=YES)
@warning In a Unix environment, the existence of a named pipe will cause this %mp_dirlist(fref=MYFREF)
@warning In a Unix environment, the existence of a named pipe will cause this
macro to hang. Therefore this tool should be used with caution in a SAS 9 web macro to hang. Therefore this tool should be used with caution in a SAS 9 web
application, as it can use up all available multibridge sessions if requests application, as it can use up all available multibridge sessions if requests
are resubmitted. are resubmitted.
If anyone finds a way to positively identify a named pipe using SAS (without If anyone finds a way to positively identify a named pipe using SAS (without
X CMD) do please raise an issue! X CMD) do please raise an issue!
@param path= for which to return contents @param path= for which to return contents
@param fref= Provide a DISK engine fileref as an alternative to PATH
@param outds= the output dataset to create @param outds= the output dataset to create
@param getattrs= YES/NO (default=NO). Uses doptname and foptname to return @param getattrs= YES/NO (default=NO). Uses doptname and foptname to return
all attributes for each file / folder. all attributes for each file / folder.
@returns outds contains the following variables: @returns outds contains the following variables:
- directory (containing folder)
- file_or_folder (file / folder) - file_or_folder (file / folder)
- filepath (path/to/file.name) - filepath (path/to/file.name)
- filename (just the file name) - filename (just the file name)
@@ -2001,18 +2007,26 @@ run;
**/ **/
%macro mp_dirlist(path=%sysfunc(pathname(work)) %macro mp_dirlist(path=%sysfunc(pathname(work))
, fref=0
, outds=work.mp_dirlist , outds=work.mp_dirlist
, getattrs=NO , getattrs=NO
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%let getattrs=%upcase(&getattrs)XX; %let getattrs=%upcase(&getattrs)XX;
data &outds (compress=no keep=file_or_folder filepath filename ext msg); data &outds (compress=no keep=file_or_folder filepath filename ext msg directory);
length filepath $500 fref fref2 $8 file_or_folder $6 filename $80 ext $20 msg $200; length directory filepath $500 fref fref2 $8 file_or_folder $6 filename $80 ext $20 msg $200;
rc = filename(fref, "&path"); %if &fref=0 %then %do;
rc = filename(fref, "&path");
%end;
%else %do;
fref="&fref";
rc=0;
%end;
if rc = 0 then do; if rc = 0 then do;
did = dopen(fref); did = dopen(fref);
directory=dinfo(did,'Directory');
if did=0 then do; if did=0 then do;
putlog "NOTE: This directory is empty - &path"; putlog "NOTE: This directory is empty - " directory;
msg=sysmsg(); msg=sysmsg();
put _all_; put _all_;
stop; stop;
@@ -2027,7 +2041,7 @@ data &outds (compress=no keep=file_or_folder filepath filename ext msg);
dnum = dnum(did); dnum = dnum(did);
do i = 1 to dnum; do i = 1 to dnum;
filename = dread(did, i); filename = dread(did, i);
rc = filename(fref2, "&path/"!!filename); rc = filename(fref2, cats(directory,'/',filename));
midd=dopen(fref2); midd=dopen(fref2);
dmsg=sysmsg(); dmsg=sysmsg();
if did > 0 then file_or_folder='folder'; if did > 0 then file_or_folder='folder';
@@ -2036,12 +2050,12 @@ data &outds (compress=no keep=file_or_folder filepath filename ext msg);
fmsg=sysmsg(); fmsg=sysmsg();
if midf > 0 then file_or_folder='file'; if midf > 0 then file_or_folder='file';
rc=fclose(midf); rc=fclose(midf);
if index(fmsg,'File is in use') or index(dmsg,'is not a directory') if index(fmsg,'File is in use') or index(dmsg,'is not a directory')
then file_or_folder='file'; then file_or_folder='file';
else if index(fmsg, 'Insufficient authorization') then file_or_folder='file'; else if index(fmsg, 'Insufficient authorization') then file_or_folder='file';
else if file_or_folder='' then file_or_folder='locked'; else if file_or_folder='' then file_or_folder='locked';
if file_or_folder='file' then do; if file_or_folder='file' then do;
ext = prxchange('s/.*\.{1,1}(.*)/$1/', 1, filename); ext = prxchange('s/.*\.{1,1}(.*)/$1/', 1, filename);
if filename = ext then ext = ' '; if filename = ext then ext = ' ';
@@ -2074,7 +2088,7 @@ run;
else do i=1 to foptnum(fid); else do i=1 to foptnum(fid);
infoname=foptname(fid,i); infoname=foptname(fid,i);
infoval=finfo(fid,infoname); infoval=finfo(fid,infoname);
sasname=compress(infoname, '_', 'adik'); sasname=compress(infoname, '_', 'adik');
if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname)); if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname));
if upcase(sasname) ne 'FILENAME' then output; if upcase(sasname) ne 'FILENAME' then output;
end; end;
@@ -2091,7 +2105,7 @@ run;
else do i=1 to doptnum(fid); else do i=1 to doptnum(fid);
infoname=doptname(fid,i); infoname=doptname(fid,i);
infoval=dinfo(fid,infoname); infoval=dinfo(fid,infoname);
sasname=compress(infoname, '_', 'adik'); sasname=compress(infoname, '_', 'adik');
if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname)); if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname));
if upcase(sasname) ne 'FILENAME' then output; if upcase(sasname) ne 'FILENAME' then output;
end; end;
@@ -2527,7 +2541,6 @@ create table &outds as
datetime2 format or regular decimal type datetime2 format or regular decimal type
@version 9.3 @version 9.3
@author Allan Bowe @author Allan Bowe
@source https://github.com/sasjs/core
**/ **/
%macro mp_getddl(libref,ds,fref=getddl,flavour=SAS,showlog=NO,schema= %macro mp_getddl(libref,ds,fref=getddl,flavour=SAS,showlog=NO,schema=

View File

@@ -1,17 +1,17 @@
/** /**
@file @file
@brief Returns all files and subdirectories within a specified parent @brief Returns all files and subdirectories within a specified parent
@details When used with getattrs=NO, is not OS specific (uses dopen / dread). @details When used with getattrs=NO, is not OS specific (uses dopen / dread).
If getattrs=YES then the doptname / foptname functions are used to scan all If getattrs=YES then the doptname / foptname functions are used to scan all
properties - any characters that are not valid in a SAS name (v7) are simply properties - any characters that are not valid in a SAS name (v7) are simply
stripped, and the table is transposed so theat each property is a column stripped, and the table is transposed so theat each property is a column
and there is one file per row. An attempt is made to get all properties and there is one file per row. An attempt is made to get all properties
whether a file or folder, but some files/folders cannot be accessed, and so whether a file or folder, but some files/folders cannot be accessed, and so
not all properties can / will be populated. not all properties can / will be populated.
Credit for the rename approach: Credit for the rename approach:
https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375/highlight/true#M5003 https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375/highlight/true#M5003
usage: usage:
@@ -20,21 +20,25 @@
%mp_dirlist(outds=cwdfileprops, getattrs=YES) %mp_dirlist(outds=cwdfileprops, getattrs=YES)
@warning In a Unix environment, the existence of a named pipe will cause this %mp_dirlist(fref=MYFREF)
@warning In a Unix environment, the existence of a named pipe will cause this
macro to hang. Therefore this tool should be used with caution in a SAS 9 web macro to hang. Therefore this tool should be used with caution in a SAS 9 web
application, as it can use up all available multibridge sessions if requests application, as it can use up all available multibridge sessions if requests
are resubmitted. are resubmitted.
If anyone finds a way to positively identify a named pipe using SAS (without If anyone finds a way to positively identify a named pipe using SAS (without
X CMD) do please raise an issue! X CMD) do please raise an issue!
@param path= for which to return contents @param path= for which to return contents
@param fref= Provide a DISK engine fileref as an alternative to PATH
@param outds= the output dataset to create @param outds= the output dataset to create
@param getattrs= YES/NO (default=NO). Uses doptname and foptname to return @param getattrs= YES/NO (default=NO). Uses doptname and foptname to return
all attributes for each file / folder. all attributes for each file / folder.
@returns outds contains the following variables: @returns outds contains the following variables:
- directory (containing folder)
- file_or_folder (file / folder) - file_or_folder (file / folder)
- filepath (path/to/file.name) - filepath (path/to/file.name)
- filename (just the file name) - filename (just the file name)
@@ -47,18 +51,26 @@
**/ **/
%macro mp_dirlist(path=%sysfunc(pathname(work)) %macro mp_dirlist(path=%sysfunc(pathname(work))
, fref=0
, outds=work.mp_dirlist , outds=work.mp_dirlist
, getattrs=NO , getattrs=NO
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%let getattrs=%upcase(&getattrs)XX; %let getattrs=%upcase(&getattrs)XX;
data &outds (compress=no keep=file_or_folder filepath filename ext msg); data &outds (compress=no keep=file_or_folder filepath filename ext msg directory);
length filepath $500 fref fref2 $8 file_or_folder $6 filename $80 ext $20 msg $200; length directory filepath $500 fref fref2 $8 file_or_folder $6 filename $80 ext $20 msg $200;
rc = filename(fref, "&path"); %if &fref=0 %then %do;
rc = filename(fref, "&path");
%end;
%else %do;
fref="&fref";
rc=0;
%end;
if rc = 0 then do; if rc = 0 then do;
did = dopen(fref); did = dopen(fref);
directory=dinfo(did,'Directory');
if did=0 then do; if did=0 then do;
putlog "NOTE: This directory is empty - &path"; putlog "NOTE: This directory is empty - " directory;
msg=sysmsg(); msg=sysmsg();
put _all_; put _all_;
stop; stop;
@@ -73,7 +85,7 @@ data &outds (compress=no keep=file_or_folder filepath filename ext msg);
dnum = dnum(did); dnum = dnum(did);
do i = 1 to dnum; do i = 1 to dnum;
filename = dread(did, i); filename = dread(did, i);
rc = filename(fref2, "&path/"!!filename); rc = filename(fref2, cats(directory,'/',filename));
midd=dopen(fref2); midd=dopen(fref2);
dmsg=sysmsg(); dmsg=sysmsg();
if did > 0 then file_or_folder='folder'; if did > 0 then file_or_folder='folder';
@@ -82,12 +94,12 @@ data &outds (compress=no keep=file_or_folder filepath filename ext msg);
fmsg=sysmsg(); fmsg=sysmsg();
if midf > 0 then file_or_folder='file'; if midf > 0 then file_or_folder='file';
rc=fclose(midf); rc=fclose(midf);
if index(fmsg,'File is in use') or index(dmsg,'is not a directory') if index(fmsg,'File is in use') or index(dmsg,'is not a directory')
then file_or_folder='file'; then file_or_folder='file';
else if index(fmsg, 'Insufficient authorization') then file_or_folder='file'; else if index(fmsg, 'Insufficient authorization') then file_or_folder='file';
else if file_or_folder='' then file_or_folder='locked'; else if file_or_folder='' then file_or_folder='locked';
if file_or_folder='file' then do; if file_or_folder='file' then do;
ext = prxchange('s/.*\.{1,1}(.*)/$1/', 1, filename); ext = prxchange('s/.*\.{1,1}(.*)/$1/', 1, filename);
if filename = ext then ext = ' '; if filename = ext then ext = ' ';
@@ -120,7 +132,7 @@ run;
else do i=1 to foptnum(fid); else do i=1 to foptnum(fid);
infoname=foptname(fid,i); infoname=foptname(fid,i);
infoval=finfo(fid,infoname); infoval=finfo(fid,infoname);
sasname=compress(infoname, '_', 'adik'); sasname=compress(infoname, '_', 'adik');
if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname)); if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname));
if upcase(sasname) ne 'FILENAME' then output; if upcase(sasname) ne 'FILENAME' then output;
end; end;
@@ -137,7 +149,7 @@ run;
else do i=1 to doptnum(fid); else do i=1 to doptnum(fid);
infoname=doptname(fid,i); infoname=doptname(fid,i);
infoval=dinfo(fid,infoname); infoval=dinfo(fid,infoname);
sasname=compress(infoname, '_', 'adik'); sasname=compress(infoname, '_', 'adik');
if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname)); if anydigit(sasname)=1 then sasname=substr(sasname,anyalpha(sasname));
if upcase(sasname) ne 'FILENAME' then output; if upcase(sasname) ne 'FILENAME' then output;
end; end;