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