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= (0) Set to 1 to enable DEBUG messages
21 
22 
23  @version 9.4
24  @author Allan Bowe
25 
26 **/
27 
28 %macro mm_createfolder(path=,mDebug=0);
29 %put &sysmacroname: execution started for &path;
30 %local dbg errorcheck;
31 %if &mDebug=0 %then %let dbg=*;
32 
33 %local parentFolderObjId child errorcheck paths;
34 %let paths=0;
35 %let errorcheck=1;
36 
37 %if &syscc ge 4 %then %do;
38  %put SYSCC=&syscc - this macro requires a clean session;
39  %return;
40 %end;
41 
42 data _null_;
43  length objId parentId objType parent child $200
44  folderPath $1000;
45  call missing (of _all_);
46  folderPath = "%trim(&path)";
47 
48  * remove any trailing slash ;
49  if ( substr(folderPath,length(folderPath),1) = '/' ) then
50  folderPath=substr(folderPath,1,length(folderPath)-1);
51 
52  * name must not be blank;
53  if ( folderPath = '' ) then do;
54  put 'ERR' +(-1) "OR: &sysmacroname PATH parameter value must be non-blank";
55  end;
56 
57  * must have a starting slash ;
58  if ( substr(folderPath,1,1) ne '/' ) then do;
59  put 'ERR' +(-1) "OR: &sysmacroname PATH param value must have starting slash";
60  stop;
61  end;
62 
63  * check if folder already exists ;
64  rc=metadata_pathobj('',cats(folderPath,"(Folder)"),"",objType,objId);
65  if rc ge 1 then do;
66  put "NOTE: Folder " folderPath " already exists!";
67  stop;
68  end;
69 
70  * do not create a root (one level) folder ;
71  if countc(folderPath,'/')=1 then do;
72  put 'ERR' +(-1) "OR: &sysmacroname will not create a new ROOT folder";
73  stop;
74  end;
75 
76  * check that root folder exists ;
77  root=cats('/',scan(folderpath,1,'/'),"(Folder)");
78  if metadata_pathobj('',root,"",objType,parentId)<1 then do;
79  put 'ERR' +(-1) "OR: " root " does not exist!";
80  stop;
81  end;
82 
83  * check that parent folder exists ;
84  child=scan(folderPath,-1,'/');
85  parent=substr(folderpath,1,length(folderpath)-length(child)-1);
86  rc=metadata_pathobj('',cats(parent,"(Folder)"),"",objType,parentId);
87  if rc<1 then do;
88  putlog 'The following folders will be created:';
89  /* folder does not exist - so start from top and work down */
90  length newpath $1000;
91  paths=0;
92  do x=2 to countw(folderpath,'/');
93  newpath='';
94  do i=1 to x;
95  newpath=cats(newpath,'/',scan(folderpath,i,'/'));
96  end;
97  rc=metadata_pathobj('',cats(newpath,"(Folder)"),"",objType,parentId);
98  if rc<1 then do;
99  paths+1;
100  call symputx(cats('path',paths),newpath);
101  putlog newpath;
102  end;
103  call symputx('paths',paths);
104  end;
105  end;
106  else putlog "parent " parent " exists";
107 
108  call symputx('parentFolderObjId',parentId,'l');
109  call symputx('child',child,'l');
110  call symputx('errorcheck',0,'l');
111 
112  &dbg put (_all_)(=);
113 run;
114 
115 %if &errorcheck=1 or &syscc ge 4 %then %return;
116 
117 %if &paths>0 %then %do x=1 %to &paths;
118  %put executing recursive call for &&path&x;
119  %mm_createfolder(path=&&path&x)
120 %end;
121 %else %do;
122  filename __newdir temp;
123  options noquotelenmax;
124  %local inmeta;
125  %put creating: &path;
126  %let inmeta=<AddMetadata><Reposid>$METAREPOSITORY</Reposid><Metadata>
127  <Tree Name='&child' PublicType='Folder' TreeType='BIP Folder'
128  UsageVersion='1000000'><ParentTree><Tree ObjRef='&parentFolderObjId'/>
129  </ParentTree></Tree></Metadata><NS>SAS</NS><Flags>268435456</Flags>
130  </AddMetadata>;
131 
132  proc metadata in="&inmeta" out=__newdir verbose;
133  run ;
134 
135  /* check it was successful */
136  data _null_;
137  length objId parentId objType parent child $200 ;
138  call missing (of _all_);
139  rc=metadata_pathobj('',cats("&path","(Folder)"),"",objType,objId);
140  if rc ge 1 then do;
141  putlog "SUCCCESS! &path created.";
142  end;
143  else do;
144  putlog 'ERR' +(-1) "OR: unsuccessful attempt to create &path";
145  call symputx('syscc',8);
146  end;
147  run;
148 
149  /* write the response to the log for debugging */
150  %if &mDebug ne 0 %then %do;
151  data _null_;
152  infile __newdir lrecl=32767;
153  input;
154  put _infile_;
155  run;
156  %end;
157  filename __newdir clear;
158 %end;
159 
160 %put &sysmacroname: execution finished for &path;
161 %mend mm_createfolder;