1 /* @source cacheensembl *******************************************************
2 **
3 ** Prepares an EMBOSS cache file for an Ensembl server
4 **
5 ** @author Copyright (C) 2011 Michael Schuster
6 ** @version $Revision: 1.8 $
7 ** @modified $Date: 2013/02/17 13:11:22 $ by $Author: mks $
8 ** @@
9 **
10 ** This program is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU General Public License
12 ** as published by the Free Software Foundation; either version 2
13 ** of the License, or (at your option) any later version.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23 **
24 ******************************************************************************/
25 
26 
27 
28 
29 /* ========================================================================= */
30 /* ============================= include files ============================= */
31 /* ========================================================================= */
32 
33 #include "emboss.h"
34 
35 
36 
37 
38 /* ========================================================================= */
39 /* ============================= private data ============================== */
40 /* ========================================================================= */
41 
42 
43 
44 
45 /* ========================================================================= */
46 /* =========================== private constants =========================== */
47 /* ========================================================================= */
48 
49 
50 
51 
52 /* ========================================================================= */
53 /* =========================== private variables =========================== */
54 /* ========================================================================= */
55 
56 
57 
58 
59 /* ========================================================================= */
60 /* =========================== private functions =========================== */
61 /* ========================================================================= */
62 
63 static int cacheensembl_stringcompare(const void* P1, const void* P2);
64 
65 static void cacheensembl_stringdelete(void** PP1, void* cl);
66 
67 
68 
69 
70 /* @prog cacheensembl *********************************************************
71 **
72 ** Prepares an EMBOSS cache file for an Ensembl server
73 **
74 ******************************************************************************/
75 
main(int argc,char ** argv)76 int main(int argc, char** argv)
77 {
78     AjPFile outf = NULL;
79     AjPFile cachef = NULL;
80 
81     AjIList iterator = NULL;
82     AjPList aliases  = NULL;
83     AjPList dbas     = NULL;
84     AjPList species  = NULL;
85 
86     AjPStr alias   = NULL;
87     AjPStr dbname  = NULL;
88     AjPStr spname  = NULL;
89     AjPStr svrname = NULL;
90     AjPStr svrurl  = NULL;
91     AjPStr special = NULL;
92     AjPStr prefix  = NULL;
93 
94     AjPTime svrtime = NULL;
95 
96     EnsEDatabaseadaptorGroup dbag = ensEDatabaseadaptorGroupNULL;
97 
98     EnsPDatabaseadaptor dba = NULL;
99 
100     EnsPDatabaseconnection dbc = NULL;
101 
102     embInit("cacheensembl", argc, argv);
103     ensInit();
104 
105     svrname = ajAcdGetString("servername");
106     outf    = ajAcdGetOutfile("outfile");
107     cachef  = ajAcdGetOutfile("cachefile");
108 
109     svrurl  = ajStrNew();
110     dbname  = ajStrNew();
111     special = ajStrNew();
112 
113     ajNamSvrGetUrl(svrname, &svrurl);
114 
115     if(!svrurl)
116         ajFatal("Could not resolve server name '%S'.", svrname);
117 
118     dbc = ensDatabaseconnectionNewUrl(svrurl);
119     ensRegistryLoadDatabaseconnection(dbc);
120     ensDatabaseconnectionDel(&dbc);
121 
122     /* Write the server file header. */
123 
124     svrtime = ajTimeNewTodayFmt("cachefile");
125     ajFmtPrintF(cachef, "# %S %D\n", ajFileGetNameS(cachef), svrtime);
126     ajTimeDel(&svrtime);
127 
128     ajFmtPrintF(cachef,
129                 "# Automatically generated by cacheensembl "
130                 "for server '%S'.\n\n",
131                 svrname);
132 
133     /*
134     ** Get all Ensembl Database Adaptor objects and write them as
135     ** EMBOSS Database definitions.
136     */
137 
138     aliases = ajListstrNew();
139     dbas    = ajListNew();
140     species = ajListstrNew();
141 
142     ensRegistryRetrieveAllSpecies(species);
143 
144     while(ajListstrPop(species, &spname))
145     {
146         ensRegistryGetAllDatabaseadaptors(ensEDatabaseadaptorGroupNULL,
147                                           spname,
148                                           dbas);
149 
150         while(ajListPop(dbas, (void**) &dba))
151         {
152             dbag = ensDatabaseadaptorGetGroup(dba);
153 
154             if(dbag == ensEDatabaseadaptorGroupNULL)
155             {
156                 ajDebug("cacheensembl main got unexpected "
157                         "Ensembl Database Adaptor Group %d.\n",
158                         dbag);
159 
160                 continue;
161             }
162 
163             ajStrAssignS(&dbname, ensDatabaseadaptorGetSpecies(dba));
164 
165             if(dbag != ensEDatabaseadaptorGroupCore)
166             {
167                 ajStrAppendC(&dbname, "_");
168                 ajStrAppendC(&dbname, ensDatabaseadaptorGroupToChar(dbag));
169             }
170 
171             prefix = NULL;
172 
173             switch(dbag)
174             {
175                 case ensEDatabaseadaptorGroupCore:
176 
177                 case ensEDatabaseadaptorGroupVega:
178 
179                 case ensEDatabaseadaptorGroupOtherFeatures:
180 
181                 case ensEDatabaseadaptorGroupCopyDNA:
182 
183                     prefix = ensRegistryGetStableidentifierprefix(dba);
184 
185                     break;
186 
187                 default:
188 
189                     break;
190             }
191 
192             ajStrAssignClear(&special);
193 
194             if((prefix != NULL) && (ajStrGetLen(prefix) > 0))
195                 ajFmtPrintAppS(&special, "SpeciesPrefix=%S;",
196                                prefix);
197 
198             if(ensDatabaseadaptorGetMultispecies(dba) == ajTrue)
199                 ajFmtPrintAppS(&special, "SpeciesIdentifier=%u;",
200                                ensDatabaseadaptorGetIdentifier(dba));
201 
202             dbc = ensDatabaseadaptorGetDatabaseconnection(dba);
203 
204             if(outf)
205                 ajFmtPrintF(outf, "%S\n", dbname);
206 
207             ajFmtPrintF(cachef, "DBNAME %S [\n",
208                         dbname);
209             ajFmtPrintF(cachef, "  dbalias: \"%S\"\n",
210                         ensDatabaseconnectionGetDatabasename(dbc));
211             ajFmtPrintF(cachef, "  release: \"%s\"\n",
212                         ensSoftwareGetVersion());
213             ajFmtPrintF(cachef, "  server:  \"%S\"\n",
214                         svrname);
215             if (ajStrGetLen(special))
216                 ajFmtPrintF(cachef, "  special: \"%S\"\n",
217                             special);
218             ajFmtPrintF(cachef, "]\n");
219             ajFmtPrintF(cachef, "\n");
220 
221             if(dbag != ensEDatabaseadaptorGroupCore)
222                 continue;
223 
224             ensRegistryAliasFetchAllbySpecies(
225                 ensDatabaseadaptorGetSpecies(dba),
226                 aliases);
227 
228             /*
229             ** Format all aliases to lower case,
230             ** sort them alphabetically and remove duplicates.
231             */
232 
233             iterator = ajListIterNew(aliases);
234             while(!ajListIterDone(iterator))
235             {
236                 alias = ajListstrIterGet(iterator);
237                 ajStrFmtLower(&alias);
238             }
239             ajListIterDel(&iterator);
240 
241             ajListSortUnique(aliases,
242                              &cacheensembl_stringcompare,
243                              &cacheensembl_stringdelete);
244 
245             alias = NULL;
246             if(ajListGetLength(aliases) > 0)
247             {
248                 while(ajListstrPop(aliases, &alias))
249                 {
250                     /*
251                     ** Reject any aliases with other than alpha-numeric
252                     ** characters like white space.
253                     */
254 
255                     if(ajStrIsAlnum(alias))
256                         ajFmtPrintF(cachef,
257                                     "ALIAS %S %S\n",
258                                     alias,
259                                     ensDatabaseadaptorGetSpecies(dba));
260 
261                     ajStrDel(&alias);
262                 }
263 
264                 ajFmtPrintF(cachef, "\n");
265             }
266 
267             /* Ensembl Database Adaptor objects *must not* be deleted. */
268         }
269 
270         ajStrDel(&spname);
271     }
272 
273     ajListstrFree(&aliases);
274     ajListstrFree(&species);
275     ajListFree(&dbas);
276 
277     ajStrDel(&svrurl);
278     ajStrDel(&dbname);
279     ajStrDel(&special);
280     ajStrDel(&svrname);
281 
282     ajFileClose(&outf);
283     ajFileClose(&cachef);
284 
285     embExit();
286 
287     return EXIT_SUCCESS;
288 }
289 
290 
291 
292 
293 /* @funcstatic cacheensembl_stringcompare *************************************
294 **
295 ** Comparison function to sort AJAX String objects case-insensitively in
296 ** ascending order.
297 **
298 ** @param [r] P1 [const void*] AJAX String 1
299 ** @param [r] P2 [const void*] AJAX String 2
300 ** @see ajListSortUnique
301 **
302 ** @return [int] The comparison function returns an integer less than,
303 **               equal to, or greater than zero if the first argument is
304 **               considered to be respectively less than, equal to, or
305 **               greater than the second.
306 ** @@
307 ******************************************************************************/
308 
cacheensembl_stringcompare(const void * P1,const void * P2)309 static int cacheensembl_stringcompare(const void* P1, const void* P2)
310 {
311     const AjPStr string1 = NULL;
312     const AjPStr string2 = NULL;
313 
314     string1 = *(AjPStr const*) P1;
315     string2 = *(AjPStr const*) P2;
316 
317 #if AJFALSE
318     if(ajDebugTest("cacheensembl_stringcompare"))
319         ajDebug("cacheensembl_stringcompare\n"
320                 "  string1 %u\n"
321                 "  string2 %u\n",
322                 string1,
323                 string2);
324 #endif
325 
326     return ajStrCmpCaseS(string1, string2);
327 }
328 
329 
330 
331 
332 /* @funcstatic cacheensembl_stringdelete **************************************
333 **
334 ** ajListSortUnique nodedelete function to delete AJAX String objects
335 ** that are redundant.
336 **
337 ** @param [r] PP1 [void**] AJAX String address 1
338 ** @param [r] cl [void*] Standard. Passed in from ajListSortUnique
339 ** @see ajListSortUnique
340 **
341 ** @return [void]
342 ** @@
343 ******************************************************************************/
344 
cacheensembl_stringdelete(void ** PP1,void * cl)345 static void cacheensembl_stringdelete(void** PP1, void* cl)
346 {
347     if(!PP1)
348         return;
349 
350     (void) cl;
351 
352     ajStrDel((AjPStr*) PP1);
353 
354     *PP1 = NULL;
355 
356     return;
357 }
358