Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
mm_createfolder.sas
Go to the documentation of this file.
1 /**
2  @file
3  @brief Recursively create a metadata folder
4  @details This macro was inspired by Paul Homes who wrote an early
5  version (mkdirmd.sas) in 2010. The original is described here:
6  https://platformadmin.com/blogs/paul/2010/07/mkdirmd/
7 
8  The macro will NOT create a new ROOT folder - not
9  because it can't, but more because that is generally not something
10  your administrator would like you to do!
11 
12  The macro is idempotent - if you run it twice, it will only create a folder
13  once.
14 
15  usage:
16 
17  %mm_createfolder(path=/some/meta/folder)
18 
19  @param path= Name of the folder to create.
20  @param mdebug= set DBG to 1 to disable DEBUG messages
21 
22  @version 9.4
23  @author Allan Bowe
24 
25 **/
26 
27 %macro mm_createfolder(path=,mDebug=0);
28 %put &sysmacroname: execution started for &path;
29 %local dbg errorcheck;
30 %if &mDebug=0 %then %let dbg=*;
31 
32 %local parentFolderObjId child errorcheck paths;
33 %let paths=0;
34 %let errorcheck=1;
35 
36 %if &syscc ge 4 %then %do;
37  %put SYSCC=&syscc - this macro requires a clean session;
38  %return;
39 %end;
40 
41 data _null_;
42  length objId parentId objType parent child $200
43  folderPath $1000;
44  call missing (of _all_);
45  folderPath = "%trim(&path)";
46 
47  * remove any trailing slash ;
48  if ( substr(folderPath,length(folderPath),1) = '/' ) then
49  folderPath=substr(folderPath,1,length(folderPath)-1);
50 
51  * name must not be blank;
52  if ( folderPath = '' ) then do;
53  put "%str(ERR)OR: &sysmacroname PATH parameter value must be non-blank";
54  end;
55 
56  * must have a starting slash ;
57  if ( substr(folderPath,1,1) ne '/' ) then do;
58  put "%str(ERR)OR: &sysmacroname PATH parameter value must have starting slash";
59  stop;
60  end;
61 
62  * check if folder already exists ;
63  rc=metadata_pathobj('',cats(folderPath,"(Folder)"),"",objType,objId);
64  if rc ge 1 then do;
65  put "NOTE: Folder " folderPath " already exists!";
66  stop;
67  end;
68 
69  * do not create a root (one level) folder ;
70  if countc(folderPath,'/')=1 then do;
71  put "%str(ERR)OR: &sysmacroname will not create a new ROOT folder";
72  stop;
73  end;
74 
75  * check that root folder exists ;
76  root=cats('/',scan(folderpath,1,'/'),"(Folder)");
77  if metadata_pathobj('',root,"",objType,parentId)<1 then do;
78  put "%str(ERR)OR: " root " does not exist!";
79  stop;
80  end;
81 
82  * check that parent folder exists ;
83  child=scan(folderPath,-1,'/');
84  parent=substr(folderpath,1,length(folderpath)-length(child)-1);
85  rc=metadata_pathobj('',cats(parent,"(Folder)"),"",objType,parentId);
86  if rc<1 then do;
87  putlog 'The following folders will be created:';
88  /* folder does not exist - so start from top and work down */
89  length newpath $1000;
90  paths=0;
91  do x=2 to countw(folderpath,'/');
92  newpath='';
93  do i=1 to x;
94  newpath=cats(newpath,'/',scan(folderpath,i,'/'));
95  end;
96  rc=metadata_pathobj('',cats(newpath,"(Folder)"),"",objType,parentId);
97  if rc<1 then do;
98  paths+1;
99  call symputx(cats('path',paths),newpath);
100  putlog newpath;
101  end;
102  call symputx('paths',paths);
103  end;
104  end;
105  else putlog "parent " parent " exists";
106 
107  call symputx('parentFolderObjId',parentId,'l');
108  call symputx('child',child,'l');
109  call symputx('errorcheck',0,'l');
110 
111  &dbg put (_all_)(=);
112 run;
113 
114 %if &errorcheck=1 or &syscc ge 4 %then %return;
115 
116 %if &paths>0 %then %do x=1 %to &paths;
117  %put executing recursive call for &&path&x;
118  %mm_createfolder(path=&&path&x)
119 %end;
120 %else %do;
121  filename __newdir temp;
122  options noquotelenmax;
123  %local inmeta;
124  %put creating: &path;
125  %let inmeta=<AddMetadata><Reposid>$METAREPOSITORY</Reposid><Metadata>
126  <Tree Name='&child' PublicType='Folder' TreeType='BIP Folder' UsageVersion='1000000'>
127  <ParentTree><Tree ObjRef='&parentFolderObjId'/></ParentTree></Tree></Metadata>
128  <NS>SAS</NS><Flags>268435456</Flags></AddMetadata>;
129 
130  proc metadata in="&inmeta" out=__newdir verbose;
131  run ;
132 
133  /* check it was successful */
134  data _null_;
135  length objId parentId objType parent child $200 ;
136  call missing (of _all_);
137  rc=metadata_pathobj('',cats("&path","(Folder)"),"",objType,objId);
138  if rc ge 1 then do;
139  putlog "SUCCCESS! &path created.";
140  end;
141  else do;
142  putlog "%str(ERR)OR: unsuccessful attempt to create &path";
143  call symputx('syscc',8);
144  end;
145  run;
146 
147  /* write the response to the log for debugging */
148  %if &mDebug ne 0 %then %do;
149  data _null_;
150  infile __newdir lrecl=32767;
151  input;
152  put _infile_;
153  run;
154  %end;
155  filename __newdir clear;
156 %end;
157 
158 %put &sysmacroname: execution finished for &path;
159 %mend;