Production Ready Macros for SAS Application Developers
https://github.com/sasjs/core
mm_createlibrary.sas
Go to the documentation of this file.
1 /**
2  @file
3  @brief Create a SAS Library
4  @details Currently only supports BASE engine
5 
6  This macro is idempotent - if you run it twice (for the same libref or
7  libname), it will only create one library. There is a dependency on other
8  macros in this library - they should be installed as a suite (see README).
9 
10  Usage:
11 
12  %mm_createlibrary(
13  libname=My New Library
14  ,libref=mynewlib
15  ,libdesc=Super & <fine>
16  ,engine=BASE
17  ,tree=/User Folders/sasdemo
18  ,servercontext=SASApp
19  ,directory=/tmp/tests
20  ,mDebug=1)
21 
22  <h4> Dependencies </h4>
23  @li mf_verifymacvars.sas
24  @li mm_createfolder.sas
25 
26 
27  @param libname= Library name (as displayed to user, 256 chars). Duplicates
28  are not created (case sensitive).
29  @param libref= Library libref (8 chars). Duplicate librefs are not created,
30  HOWEVER- the check is not case sensitive - if *libref* exists, *LIBREF*
31  will still be created. Librefs created will always be uppercased.
32  @param engine= Library engine (currently only BASE supported)
33  @param tree= The metadata folder uri, or the metadata path, in which to
34  create the library.
35  @param servercontext= The SAS server against which the library is registered.
36  @param IsPreassigned= set to 1 if the library should be pre-assigned.
37 
38  @param libdesc= Library description (optional)
39  @param directory= Required for the BASE engine. The metadata directory objects
40  are searched to find an existing one with a matching physical path.
41  If more than one uri found with that path, then the first one will be used.
42  If no URI is found, a new directory object will be created. The physical
43  path will also be created, if it doesn't exist.
44 
45 
46  @param mDebug= set to 1 to show debug messages in the log
47  @param frefin= fileref to use (enables change if there is a conflict). The
48  filerefs are left open, to enable inspection after running the
49  macro (or importing into an xmlmap if needed).
50  @param frefout= fileref to use (enables change if there is a conflict)
51 
52 
53  @version 9.3
54  @author Allan Bowe
55 
56 **/
57 
58 %macro mm_createlibrary(
59  libname=My New Library
60  ,libref=mynewlib
61  ,libdesc=Created automatically using the mm_createlibrary macro
62  ,engine=BASE
63  ,tree=/User Folders/sasdemo
64  ,servercontext=SASApp
65  ,directory=/tmp/somelib
66  ,IsPreassigned=0
67  ,mDebug=0
68  ,frefin=mm_in
69  ,frefout=mm_out
70 )/*/STORE SOURCE*/;
71 
72 %local mD;
73 %if &mDebug=1 %then %let mD=;
74 %else %let mD=%str(*);
75 %&mD.put Executing &sysmacroname..sas;
76 %&mD.put _local_;
77 
78 %let libref=%upcase(&libref);
79 
80 /**
81  * Check Library does not exist already with this libname
82  */
83 data _null_;
84  length type uri $256;
85  rc=metadata_resolve("omsobj:SASLibrary?@Name='&libname'",type,uri);
86  call symputx('checktype',type,'l');
87  call symputx('liburi',uri,'l');
88  putlog (_all_)(=);
89 run;
90 %if &checktype = SASLibrary %then %do;
91  %put WARNING: Library (&liburi) already exists with libname (&libname) ;
92  %return;
93 %end;
94 
95 /**
96  * Check Library does not exist already with this libref
97  */
98 data _null_;
99  length type uri $256;
100  rc=metadata_resolve("omsobj:SASLibrary?@Libref='&libref'",type,uri);
101  call symputx('checktype',type,'l');
102  call symputx('liburi',uri,'l');
103  putlog (_all_)(=);
104 run;
105 %if &checktype = SASLibrary %then %do;
106  %put WARNING: Library (&liburi) already exists with libref (&libref) ;
107  %return;
108 %end;
109 
110 
111 /**
112  * Attempt to create tree
113  */
114 %mm_createfolder(path=&tree)
115 
116 /**
117  * check tree exists
118  */
119 data _null_;
120  length type uri $256;
121  rc=metadata_pathobj("","&tree","Folder",type,uri);
122  call symputx('foldertype',type,'l');
123  call symputx('treeuri',uri,'l');
124 run;
125 %if &foldertype ne Tree %then %do;
126  %put WARNING: Tree &tree does not exist!;
127  %return;
128 %end;
129 
130 /**
131  * Create filerefs for proc metadata call
132  */
133 filename &frefin temp;
134 filename &frefout temp;
135 
136 %if &engine=BASE %then %do;
137 
138  %mf_verifymacvars(libname libref engine servercontext tree)
139 
140 
141 
142  /**
143  * Check that the ServerContext exists
144  */
145  data _null_;
146  length type uri $256;
147  rc=metadata_resolve("omsobj:ServerContext?@Name='&ServerContext'",type,uri);
148  call symputx('checktype',type,'l');
149  call symputx('serveruri',uri,'l');
150  putlog (_all_)(=);
151  run;
152  %if &checktype ne ServerContext %then %do;
153  %put %str(ERR)OR: ServerContext (&ServerContext) does not exist!;
154  %return;
155  %end;
156 
157  /**
158  * Get prototype info
159  */
160  data _null_;
161  length type uri str $256;
162  str="omsobj:Prototype?@Name='Library.SAS.Prototype.Name.xmlKey.txt'";
163  rc=metadata_resolve(str,type,uri);
164  call symputx('checktype',type,'l');
165  call symputx('prototypeuri',uri,'l');
166  putlog (_all_)(=);
167  run;
168  %if &checktype ne Prototype %then %do;
169  %put %str(ERR)OR: Prototype (Library.SAS.Prototype.Name.xmlKey.txt) not found!;
170  %return;
171  %end;
172 
173  /**
174  * Check that Physical location exists
175  */
176  %if %sysfunc(fileexist(&directory))=0 %then %do;
177  %put %str(ERR)OR: Physical directory (&directory) does not appear to exist!;
178  %return;
179  %end;
180 
181  /**
182  * Check that Directory Object exists in metadata
183  */
184  data _null_;
185  length type uri $256;
186  rc=metadata_resolve("omsobj:Directory?@DirectoryRole='LibraryPath'"
187  !!" and @DirectoryName='&directory'",type,uri);
188  call symputx('checktype',type,'l');
189  call symputx('directoryuri',uri,'l');
190  putlog (_all_)(=);
191  run;
192  %if &checktype ne Directory %then %do;
193  %put NOTE: Directory object does not exist for (&directory) location;
194  %put NOTE: It will now be created;
195 
196  data _null_;
197  file &frefin;
198  directory=quote(symget('directory'));
199  put "<AddMetadata><Reposid>$METAREPOSITORY</Reposid><Metadata> "/
200  '<Directory UsageVersion="1000000" IsHidden="0" IsRelative="0"'/
201  ' DirectoryRole="LibraryPath" Name="Path" DirectoryName=' directory '/>'/
202  "</Metadata><NS>SAS</NS>"/
203  "<Flags>268435456</Flags></AddMetadata>";
204  run;
205 
206  proc metadata in= &frefin out=&frefout %if &mdebug=1 %then verbose;;
207  run;
208  %if &mdebug=1 %then %do;
209  data _null_;
210  infile &frefout lrecl=1048576;
211  input; put _infile_;
212  run;
213  %end;
214  %put NOTE: Checking to ensure directory (&directory) object was created;
215  data _null_;
216  length type uri $256;
217  rc=metadata_resolve("omsobj:Directory?@DirectoryRole='LibraryPath'"
218  !!" and @DirectoryName='&directory'",type,uri);
219  call symputx('checktype2',type,'l');
220  call symputx('directoryuri',uri,'l');
221  %if &mdebug=1 %then putlog (_all_)(=);;
222  run;
223  %if &checktype2 ne Directory %then %do;
224  %put %str(ERR)OR: Directory (&directory) object was NOT created!;
225  %return;
226  %end;
227  %else %put NOTE: Directory (&directoryuri) successfully created!;
228  %end;
229 
230  /**
231  * check SAS version
232  */
233  %if %sysevalf(&sysver lt 9.3) %then %do;
234  %put WARNING: Version 9.3 or later required;
235  %return;
236  %end;
237 
238  /**
239  * Prepare the XML and create the library
240  */
241  data _null_;
242  file &frefin;
243  treeuri=quote(symget('treeuri'));
244  serveruri=quote(symget('serveruri'));
245  directoryuri=quote(symget('directoryuri'));
246  libname=quote(symget('libname'));
247  libref=quote(symget('libref'));
248  IsPreassigned=quote(symget('IsPreassigned'));
249  prototypeuri=quote(symget('prototypeuri'));
250 
251  /* escape description so it can be stored as XML */
252  libdesc=tranwrd(symget('libdesc'),'&','&amp;');
253  libdesc=tranwrd(libdesc,'<','&lt;');
254  libdesc=tranwrd(libdesc,'>','&gt;');
255  libdesc=tranwrd(libdesc,"'",'&apos;');
256  libdesc=tranwrd(libdesc,'"','&quot;');
257  libdesc=tranwrd(libdesc,'0A'x,'&#10;');
258  libdesc=tranwrd(libdesc,'0D'x,'&#13;');
259  libdesc=tranwrd(libdesc,'$','&#36;');
260  libdesc=quote(trim(libdesc));
261 
262  put "<AddMetadata><Reposid>$METAREPOSITORY</Reposid><Metadata> "/
263  '<SASLibrary Desc=' libdesc ' Engine="BASE" IsDBMSLibname="0" '/
264  ' IsHidden="0" IsPreassigned=' IsPreassigned ' Libref=' libref /
265  ' UsageVersion="1000000" PublicType="Library" name=' libname '>'/
266  ' <DeployedComponents>'/
267  ' <ServerContext ObjRef=' serveruri "/>"/
268  ' </DeployedComponents>'/
269  ' <PropertySets>'/
270  ' <PropertySet Name="ModifiedByProductPropertySet" '/
271  ' SetRole="ModifiedByProductPropertySet" UsageVersion="0" />'/
272  ' </PropertySets>'/
273  " <Trees><Tree ObjRef=" treeuri "/></Trees>"/
274  ' <UsingPackages> '/
275  ' <Directory ObjRef=' directoryuri ' />'/
276  ' </UsingPackages>'/
277  ' <UsingPrototype>'/
278  ' <Prototype ObjRef=' prototypeuri '/>'/
279  ' </UsingPrototype>'/
280  '</SASLibrary></Metadata><NS>SAS</NS>'/
281  '<Flags>268435456</Flags></AddMetadata>';
282  run;
283 
284 
285  proc metadata in= &frefin out=&frefout %if &mdebug=1 %then verbose ;;
286  run;
287 
288  %if &mdebug=1 %then %do;
289  data _null_;
290  infile &frefout lrecl=1048576;
291  input;put _infile_;
292  run;
293  %end;
294  %put NOTE: Checking to ensure library (&libname) was created;
295  data _null_;
296  length type uri $256;
297  rc=metadata_pathobj("","&tree/&libname","Library",type,uri);
298  call symputx('libtype',type,'l');
299  call symputx('liburi',uri,'l');
300  %if &mdebug=1 %then putlog (_all_)(=);;
301  run;
302  %if &libtype ne SASLibrary %then %do;
303  %put %str(ERR)OR: Could not find (&libname) at (&tree)!!;
304  %return;
305  %end;
306  %else %put NOTE: Library (&libname) successfully created in (&tree)!;
307 %end;
308 %else %do;
309  %put %str(ERR)OR: Other library engine types are not yet supported!!;
310 %end;
311 
312 
313 /**
314  * Wrap up
315  */
316 %if &mdebug ne 1 %then %do;
317  filename &frefin clear;
318  filename &frefout clear;
319 %end;
320 
321 %mend;