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%mp_abort(iftrue= (
137 &engine=BASE & %mf_verifymacvars(libname libref engine servercontext tree)=0
138 )
139 ,mac=&sysmacroname
140 ,msg=%str(Empty inputs: libname libref engine servercontext tree)
141)
142
143%if &engine=BASE %then %do;
144 /**
145 * Check that the ServerContext exists
146 */
147 data _null_;
148 length type uri $256;
149 rc=metadata_resolve("omsobj:ServerContext?@Name='&ServerContext'",type,uri);
150 call symputx('checktype',type,'l');
151 call symputx('serveruri',uri,'l');
152 putlog (_all_)(=);
153 run;
154 %if &checktype ne ServerContext %then %do;
155 %put %str(ERR)OR: ServerContext (&ServerContext) does not exist!;
156 %return;
157 %end;
158
159 /**
160 * Get prototype info
161 */
162 data _null_;
163 length type uri str $256;
164 str="omsobj:Prototype?@Name='Library.SAS.Prototype.Name.xmlKey.txt'";
165 rc=metadata_resolve(str,type,uri);
166 call symputx('checktype',type,'l');
167 call symputx('prototypeuri',uri,'l');
168 putlog (_all_)(=);
169 run;
170 %if &checktype ne Prototype %then %do;
171 %put %str(ERR)OR: Prototype Library.SAS.Prototype.Name.xmlKey.txt not found;
172 %return;
173 %end;
174
175 /**
176 * Check that Physical location exists
177 */
178 %if %sysfunc(fileexist(&directory))=0 %then %do;
179 %put %str(ERR)OR: Physical directory (&directory) does not appear to exist!;
180 %return;
181 %end;
182
183 /**
184 * Check that Directory Object exists in metadata
185 */
186 data _null_;
187 length type uri $256;
188 rc=metadata_resolve("omsobj:Directory?@DirectoryRole='LibraryPath'"
189 !!" and @DirectoryName='&directory'",type,uri);
190 call symputx('checktype',type,'l');
191 call symputx('directoryuri',uri,'l');
192 putlog (_all_)(=);
193 run;
194 %if &checktype ne Directory %then %do;
195 %put NOTE: Directory object does not exist for (&directory) location;
196 %put NOTE: It will now be created;
197
198 data _null_;
199 file &frefin;
200 directory=quote(symget('directory'));
201 put "<AddMetadata><Reposid>$METAREPOSITORY</Reposid><Metadata> "/
202 '<Directory UsageVersion="1000000" IsHidden="0" IsRelative="0"'/
203 ' DirectoryRole="LibraryPath" Name="Path" DirectoryName=' directory '/>'/
204 "</Metadata><NS>SAS</NS>"/
205 "<Flags>268435456</Flags></AddMetadata>";
206 run;
207
208 proc metadata in= &frefin out=&frefout %if &mdebug=1 %then verbose;;
209 run;
210 %if &mdebug=1 %then %do;
211 data _null_;
212 infile &frefout lrecl=1048576;
213 input; put _infile_;
214 run;
215 %end;
216 %put NOTE: Checking to ensure directory (&directory) object was created;
217 data _null_;
218 length type uri $256;
219 rc=metadata_resolve("omsobj:Directory?@DirectoryRole='LibraryPath'"
220 !!" and @DirectoryName='&directory'",type,uri);
221 call symputx('checktype2',type,'l');
222 call symputx('directoryuri',uri,'l');
223 %if &mdebug=1 %then putlog (_all_)(=);;
224 run;
225 %if &checktype2 ne Directory %then %do;
226 %put %str(ERR)OR: Directory (&directory) object was NOT created!;
227 %return;
228 %end;
229 %else %put NOTE: Directory (&directoryuri) successfully created!;
230 %end;
231
232 /**
233 * check SAS version
234 */
235 %if %sysevalf(&sysver lt 9.3) %then %do;
236 %put %str(WARN)ING: Version 9.3 or later required;
237 %return;
238 %end;
239
240 /**
241 * Prepare the XML and create the library
242 */
243 data _null_;
244 file &frefin;
245 treeuri=quote(symget('treeuri'));
246 serveruri=quote(symget('serveruri'));
247 directoryuri=quote(symget('directoryuri'));
248 libname=quote(symget('libname'));
249 libref=quote(symget('libref'));
250 IsPreassigned=quote(symget('IsPreassigned'));
251 prototypeuri=quote(symget('prototypeuri'));
252
253 /* escape description so it can be stored as XML */
254 libdesc=tranwrd(symget('libdesc'),'&','&amp;');
255 libdesc=tranwrd(libdesc,'<','&lt;');
256 libdesc=tranwrd(libdesc,'>','&gt;');
257 libdesc=tranwrd(libdesc,"'",'&apos;');
258 libdesc=tranwrd(libdesc,'"','&quot;');
259 libdesc=tranwrd(libdesc,'0A'x,'&#10;');
260 libdesc=tranwrd(libdesc,'0D'x,'&#13;');
261 libdesc=tranwrd(libdesc,'$','&#36;');
262 libdesc=quote(trim(libdesc));
263
264 put "<AddMetadata><Reposid>$METAREPOSITORY</Reposid><Metadata> "/
265 '<SASLibrary Desc=' libdesc ' Engine="BASE" IsDBMSLibname="0" '/
266 ' IsHidden="0" IsPreassigned=' IsPreassigned ' Libref=' libref /
267 ' UsageVersion="1000000" PublicType="Library" name=' libname '>'/
268 ' <DeployedComponents>'/
269 ' <ServerContext ObjRef=' serveruri "/>"/
270 ' </DeployedComponents>'/
271 ' <PropertySets>'/
272 ' <PropertySet Name="ModifiedByProductPropertySet" '/
273 ' SetRole="ModifiedByProductPropertySet" UsageVersion="0" />'/
274 ' </PropertySets>'/
275 " <Trees><Tree ObjRef=" treeuri "/></Trees>"/
276 ' <UsingPackages> '/
277 ' <Directory ObjRef=' directoryuri ' />'/
278 ' </UsingPackages>'/
279 ' <UsingPrototype>'/
280 ' <Prototype ObjRef=' prototypeuri '/>'/
281 ' </UsingPrototype>'/
282 '</SASLibrary></Metadata><NS>SAS</NS>'/
283 '<Flags>268435456</Flags></AddMetadata>';
284 run;
285
286
287 proc metadata in= &frefin out=&frefout %if &mdebug=1 %then verbose ;;
288 run;
289
290 %if &mdebug=1 %then %do;
291 data _null_;
292 infile &frefout lrecl=1048576;
293 input;put _infile_;
294 run;
295 %end;
296 %put NOTE: Checking to ensure library (&libname) was created;
297 data _null_;
298 length type uri $256;
299 rc=metadata_pathobj("","&tree/&libname","Library",type,uri);
300 call symputx('libtype',type,'l');
301 call symputx('liburi',uri,'l');
302 %if &mdebug=1 %then putlog (_all_)(=);;
303 run;
304 %if &libtype ne SASLibrary %then %do;
305 %put %str(ERR)OR: Could not find (&libname) at (&tree)!!;
306 %return;
307 %end;
308 %else %put NOTE: Library (&libname) successfully created in (&tree)!;
309%end;
310%else %do;
311 %put %str(ERR)OR: Other library engine types are not yet supported!!;
312%end;
313
314
315/**
316 * Wrap up
317 */
318%if &mdebug ne 1 %then %do;
319 filename &frefin clear;
320 filename &frefout clear;
321%end;
322
323%mend mm_createlibrary;