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> SAS Macros </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 */
83data _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_)(=);
89run;
90%if &checktype = SASLibrary %then %do;
91 %put %str(WARN)ING: Library (&liburi) already exists with libname (&libname);
92 %return;
93%end;
94
95/**
96 * Check Library does not exist already with this libref
97 */
98data _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_)(=);
104run;
105%if &checktype = SASLibrary %then %do;
106 %put %str(WARN)ING: 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 */
119data _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');
124run;
125%if &foldertype ne Tree %then %do;
126 %put %str(WARN)ING: Tree &tree does not exist!;
127 %return;
128%end;
129
130/**
131 * Create filerefs for proc metadata call
132 */
133filename &frefin temp;
134filename &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 %str(WARN)ING: 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 mm_createlibrary;