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 [in] path= Name of the folder to create.
20 @param [in] 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
41data _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 param 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_)(=);
112run;
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'
127 UsageVersion='1000000'><ParentTree><Tree ObjRef='&parentFolderObjId'/>
128 </ParentTree></Tree></Metadata><NS>SAS</NS><Flags>268435456</Flags>
129 </AddMetadata>;
130
131 proc metadata in="&inmeta" out=__newdir verbose;
132 run ;
133
134 /* check it was successful */
135 data _null_;
136 length objId parentId objType parent child $200 ;
137 call missing (of _all_);
138 rc=metadata_pathobj('',cats("&path","(Folder)"),"",objType,objId);
139 if rc ge 1 then do;
140 putlog "SUCCCESS! &path created.";
141 end;
142 else do;
143 putlog "%str(ERR)OR: unsuccessful attempt to create &path";
144 call symputx('syscc',8);
145 end;
146 run;
147
148 /* write the response to the log for debugging */
149 %if &mDebug ne 0 %then %do;
150 data _null_;
151 infile __newdir lrecl=32767;
152 input;
153 put _infile_;
154 run;
155 %end;
156 filename __newdir clear;
157%end;
158
159%put &sysmacroname: execution finished for &path;
160%mend mm_createfolder;