1 /*   pmfapi.c
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *            National Center for Biotechnology Information (NCBI)
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government do not place any restriction on its use or reproduction.
13 *  We would, however, appreciate having the NCBI and the author cited in
14 *  any work or product based on this material
15 *
16 *  Although all reasonable efforts have been taken to ensure the accuracy
17 *  and reliability of the software and data, the NLM and the U.S.
18 *  Government do not and cannot warrant the performance or results that
19 *  may be obtained by using this software or data. The NLM and the U.S.
20 *  Government disclaim all warranties, express or implied, including
21 *  warranties of performance, merchantability or fitness for any particular
22 *  purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name:  pmfapi.c
27 *
28 * Author:  Jonathan Kans
29 *
30 * Version Creation Date:   5/5/00
31 *
32 * $Revision: 1.120 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 *
39 * ==========================================================================
40 */
41 
42 #include <ncbi.h>
43 #include <pmfapi.h>
44 #include <objmedli.h>
45 #include <objpubme.h>
46 #include <objsset.h>
47 #include <objmgr.h>
48 #include <sequtil.h>
49 #include <sqnutils.h>
50 
51 #ifdef OS_MAC
52 #include <Events.h>
53 #endif
54 
55 #ifdef OS_UNIX
56 #include <sys/times.h>
57 #include <limits.h>
58 #endif
59 
60 
61 /* ml to std code modified from original in medutil.c */
62 
AllUpperCase(CharPtr p)63 static Boolean AllUpperCase (
64   CharPtr p
65 )
66 
67 {
68   Char  ch;
69 
70   if (p == NULL) return FALSE;
71   ch = *p;
72   while (ch != '\0') {
73     if (! IS_UPPER (ch)) return FALSE;
74     p++;
75     ch = *p;
76   }
77   return TRUE;
78 }
79 
80 
SplitMLAuthorName(CharPtr name,CharPtr last,CharPtr initials,CharPtr suffix)81 static void SplitMLAuthorName (
82   CharPtr name,
83   CharPtr last,
84   CharPtr initials,
85   CharPtr suffix
86 )
87 
88 {
89   CharPtr  p, p2;
90   Int2     i;
91   Char     sbuf [20], ibuf [20];
92 
93   /* Clear the ibuf field and transfer the entire name to 'last',
94   excluding leading and trailing spaces */
95 
96   if (name == NULL) return;
97 
98   ibuf [0] = '\0';
99   sbuf [0] = '\0';
100   last [0] = '\0';
101   initials [0] = '\0';
102   suffix [0] = '\0';
103   while (*name <= ' ') {
104     name++;
105     if (*name == '\0') return;
106   }
107   StringCpy( last, name );
108 
109   for (i=StringLen (last) - 1; ((i >= 0) && (last [i] <= ' ')); i--) {
110     last[i] = '\0';
111   }
112 
113   /* Strip off the last token (initials or name suffix (Jr, Sr, suffix.) */
114 
115   p = StringRChr (last, (int) ' ');
116   if (p != NULL) { /* more than just last name */
117 
118     /* Separate the token from the last name */
119 
120     p2 = p + 1;
121     while ((p > last) && (*p == ' ')) {
122       *p = '\0';
123       p--;
124     }
125 
126     /* If the last token is not all upper case, and there are more than
127     two tokens, see if the next to the last are initials (upper case) */
128 
129     if (! AllUpperCase (p2) && (p = StringRChr (last, (int) ' ' )) != NULL) {
130 
131       /* We have at least three tokens, is the next to last initials? */
132 
133       if (AllUpperCase (p + 1)) {
134 
135         /* Yes - concatenate the last two tokens as initials */
136 
137         StringCpy (ibuf, p + 1);
138         StringCpy (sbuf, p2);
139         while (p > last && (*p == ' ')) {
140           *p = '\0';
141           p--;
142         }
143       }
144     }
145 
146     if (ibuf [0] == '\0') { /* Only the last token goes in ibuf */
147       StringCpy (ibuf, p2);
148     }
149   }
150 
151   /* now add periods to ibuf and convert suffix */
152 
153   for (p = initials, p2 = ibuf; *p2 != '\0'; p2++, p++) {
154     *p = *p2;
155     if (! IS_LOWER(*(p2 + 1))) { /* watch out for foreign names */
156       p++;
157       *p = '.';
158     }
159   }
160   *p = '\0';
161 
162   if (sbuf [0]) {
163     if (StringCmp (sbuf, "1d") == 0 || StringCmp (sbuf, "1st") == 0)
164       p = StringMove (suffix, "I");
165     else if (StringCmp (sbuf, "2d") == 0 || StringCmp (sbuf, "2nd") == 0)
166       p = StringMove (suffix, "II");
167     else if (StringCmp (sbuf, "3d") == 0 || StringCmp (sbuf, "3rd") == 0)
168       p = StringMove (suffix, "III");
169     else if (StringCmp (sbuf, "4th") == 0)
170       p = StringMove (suffix, "IV");
171     else if (StringCmp (sbuf, "5th") == 0)
172       p = StringMove (suffix, "V");
173     else if (StringCmp (sbuf, "6th") == 0)
174       p = StringMove (suffix, "VI");
175     else if (StringCmp (sbuf, "Sr") == 0)
176       p = StringMove (suffix, "Sr.");
177     else if (StringCmp (sbuf, "Jr") == 0)
178       p = StringMove (suffix, "Jr.");
179     else
180       p = StringMove (suffix, sbuf);
181   }
182 }
183 
184 
ConvertMLtoSTD(CharPtr token)185 static ValNodePtr ConvertMLtoSTD (
186   CharPtr token
187 )
188 
189 {
190   AuthorPtr   aup;
191   CharPtr     eptr;
192   Char        last [80], initials [20], suffix [20];
193   NameStdPtr  nsp;
194   PersonIdPtr pid;
195   ValNodePtr  vnp;
196 
197   if (token == NULL) return NULL;
198   for (eptr = token + StringLen (token) - 1;
199        eptr > token && *eptr == ' ';
200        eptr--) continue;
201 
202   SplitMLAuthorName (token, last, initials, suffix);
203 
204   nsp = NameStdNew ();
205   if (nsp == NULL) return NULL;
206   nsp->names [0] = StringSave (last);
207   if (initials [0] != '\0') {
208     nsp->names[4] = StringSave (initials);
209   }
210   if (suffix[0] != '\0') {
211     nsp->names[5] = StringSave (suffix);
212   }
213   if (nsp->names[0] != NULL) {
214     pid = PersonIdNew ();
215     pid->choice = 2; /* name */
216     pid->data = nsp;
217     aup = AuthorNew ();
218     aup->name = pid;
219     vnp = ValNodeNew (NULL);
220     vnp->data.ptrvalue = (Pointer) aup;
221     return vnp;
222   }
223   return NULL;
224 }
225 
226 
ChangeMedlineAuthorsToISO(MedlineEntryPtr mep)227 static void ChangeMedlineAuthorsToISO (
228   MedlineEntryPtr mep
229 )
230 
231 {
232   AuthListPtr  alp;
233   CitArtPtr    cap;
234   ValNodePtr   curr, oldnames, tmp, v;
235 
236   if (mep == NULL) return;
237   cap = mep->cit;
238   if (cap == NULL) return;
239   alp = cap->authors;
240   if (alp == NULL || alp->choice != 2) return;
241 
242   /* do not convert if too big for buffers */
243 
244   for (tmp = alp->names; tmp != NULL; tmp = tmp->next) {
245     if (StringLen ((CharPtr) tmp->data.ptrvalue) > 70) return;
246   }
247 
248   oldnames = alp->names;
249   alp->names = NULL;
250   alp->choice = 1; /* make std names */
251 
252   for (tmp = oldnames; tmp != NULL; tmp = tmp->next) {
253     curr = ConvertMLtoSTD ((CharPtr) tmp->data.ptrvalue);
254     if (alp->names == NULL) {
255       alp->names = curr;
256     } else {
257       for (v = alp->names; v->next != NULL; v = v->next) continue;
258       v->next = curr;
259     }
260   }
261 
262   ValNodeFreeData (oldnames);
263 }
264 
265 
266 static Boolean log_query_url = FALSE;
267 static Boolean log_query_url_set = FALSE;
268 
269 
PubMedFetchOpenConnection(Int4 uid)270 NLM_EXTERN CONN PubMedFetchOpenConnection (
271   Int4 uid
272 )
273 
274 {
275   Char  query [80];
276 
277   if (uid < 1) return NULL;
278 
279   /*
280   sprintf (query, "db=PubMed&retmode=asn.1&id=%ld", (long) uid);
281   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/eutils/efetch.fcgi",
282                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
283                              eMIME_AsnText, eENCOD_None, 0);
284   */
285 
286   sprintf (query, "id=%ld", (long) uid);
287   return QUERY_OpenServiceQueryEx ("PubFetch", query, 30, query + 3);
288 }
289 
290 
MakeDateTimeStamp(CharPtr buf)291 static void MakeDateTimeStamp (
292   CharPtr buf
293 )
294 
295 {
296   DayTime  dt;
297 
298   if (buf == NULL) return;
299   *buf = '\0';
300 
301   if (GetDayTime (&dt)) {
302     sprintf (buf, "%02ld/%02ld/%4ld %02ld:%02ld:%02ld",
303              (long) (dt.tm_mon + 1), (long) dt.tm_mday, (long) (dt.tm_year + 1900),
304              (long) dt.tm_hour, (long) dt.tm_min, (long) dt.tm_sec);
305   }
306 }
307 
308 
PubSeqFetchOpenConnection(BIG_ID uid,Int2 retcode,Int4 flags)309 NLM_EXTERN CONN PubSeqFetchOpenConnection (
310   BIG_ID uid,
311   Int2 retcode,
312   Int4 flags
313 )
314 
315 {
316   Char     buf [40];
317   CONN     conn;
318   Char     query [80];
319 #ifdef OS_UNIX
320   CharPtr  str;
321 #endif
322 
323   if (uid < 1) return NULL;
324   if (retcode < 0 || retcode > 4) {
325     retcode = 0;
326   }
327   if (flags < 0) {
328     flags = -1;
329   }
330 
331 #ifdef PUB_SEQ_FETCH_DEBUG
332   sprintf (query, "save=idf&view=1&maxplex=%d&extrafeat=%ld&val=%lld", (int) retcode, (long) flags, (long long) uid);
333   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/viewer.fcgi",
334                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
335                              eMIME_AsnText, eENCOD_None, 0);
336 #endif
337 
338   sprintf (query, "maxplex=%d&extrafeat=%ld&val=%lld", (int) retcode, (long) flags, (long long) uid);
339   conn = QUERY_OpenServiceQueryEx ("SeqFetch", query, 30, StringRChr (query, '=') + 1);
340 
341 #ifdef OS_UNIX
342   if (! log_query_url_set) {
343     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
344     if (StringDoesHaveText (str)) {
345       if (StringICmp (str, "TRUE") == 0) {
346         log_query_url = TRUE;
347       }
348     }
349     log_query_url_set = TRUE;
350   }
351 #endif
352 
353   if (conn == NULL) {
354     MakeDateTimeStamp (buf);
355     if (StringHasNoText (buf)) {
356       StringCpy (buf, "?");
357     }
358     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchOpenConnection failed for gi %lld, date/time %s", (long long) uid, buf);
359     return conn;
360   }
361 
362 #ifdef OS_UNIX
363   if (log_query_url) {
364     str = CONN_Description (conn);
365     if (str == NULL) {
366       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for gi %lld", (long long) uid);
367     } else {
368       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for gi %lld is %s", (long long) uid, str);
369     }
370     MemFree (str);
371   }
372 #endif
373 
374   return conn;
375 }
376 
377 
PubSeqFetchOpenConnectionString(CharPtr id,Int2 retcode,Int4 flags)378 NLM_EXTERN CONN PubSeqFetchOpenConnectionString (
379   CharPtr id,
380   Int2 retcode,
381   Int4 flags
382 )
383 
384 {
385   Char     buf [40];
386   CONN     conn;
387   Char     query [80];
388 #ifdef OS_UNIX
389   CharPtr  str;
390 #endif
391 
392   if (StringHasNoText (id)) return NULL;
393   if (retcode < 0 || retcode > 4) {
394     retcode = 0;
395   }
396   if (flags < 0) {
397     flags = -1;
398   }
399 
400 #ifdef PUB_SEQ_FETCH_DEBUG
401   sprintf (query, "save=idf&view=1&maxplex=%d&extrafeat=%ld&val=%s", (int) retcode, (long) flags, id);
402   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/viewer.fcgi",
403                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
404                              eMIME_AsnText, eENCOD_None, 0);
405 #endif
406 
407   sprintf (query, "maxplex=%d&extrafeat=%ld&val=%s", (int) retcode, (long) flags, id);
408   conn = QUERY_OpenServiceQueryEx ("SeqFetch", query, 30, StringRChr (query, '=') + 1);
409 
410 #ifdef OS_UNIX
411   if (! log_query_url_set) {
412     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
413     if (StringDoesHaveText (str)) {
414       if (StringICmp (str, "TRUE") == 0) {
415         log_query_url = TRUE;
416       }
417     }
418     log_query_url_set = TRUE;
419   }
420 #endif
421 
422   if (conn == NULL) {
423     MakeDateTimeStamp (buf);
424     if (StringHasNoText (buf)) {
425       StringCpy (buf, "?");
426     }
427     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchOpenConnection failed for id %s, date/time %s", id, buf);
428     return conn;
429   }
430 
431 #ifdef OS_UNIX
432   if (log_query_url) {
433     str = CONN_Description (conn);
434     if (str == NULL) {
435       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for id %s", id);
436     } else {
437       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for id %s is %s", id, str);
438     }
439     MemFree (str);
440   }
441 #endif
442 
443   return conn;
444 }
445 
446 
PubSeqFetchTraceOpenConnection(Uint4 tid,Int2 retcode,Int4 flags)447 NLM_EXTERN CONN PubSeqFetchTraceOpenConnection (
448   Uint4 tid,
449   Int2 retcode,
450   Int4 flags
451 )
452 
453 {
454   Char     buf [40];
455   CONN     conn;
456   Char     query [80];
457 #ifdef OS_UNIX
458   CharPtr  str;
459 #endif
460 
461   if (tid < 1) return NULL;
462   if (retcode < 0 || retcode > 4) {
463     retcode = 0;
464   }
465   if (flags < 0) {
466     flags = -1;
467   }
468 
469 #ifdef PUB_SEQ_FETCH_DEBUG
470   sprintf (query, "save=idf&view=1&maxplex=%d&extrafeat=%ld&val=0:TRACE:%lu", (int) retcode, (long) flags, (unsigned long) tid);
471   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/viewer.fcgi",
472                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
473                              eMIME_AsnText, eENCOD_None, 0);
474 #endif
475 
476   sprintf (query, "maxplex=%d&extrafeat=%ld&val=0:TRACE:%lu", (int) retcode, (long) flags, (unsigned long) tid);
477   conn = QUERY_OpenServiceQueryEx ("SeqFetch", query, 30, StringRChr (query, ':') + 1);
478 
479 #ifdef OS_UNIX
480   if (! log_query_url_set) {
481     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
482     if (StringDoesHaveText (str)) {
483       if (StringICmp (str, "TRUE") == 0) {
484         log_query_url = TRUE;
485       }
486     }
487     log_query_url_set = TRUE;
488   }
489 #endif
490 
491   if (conn == NULL) {
492     MakeDateTimeStamp (buf);
493     if (StringHasNoText (buf)) {
494       StringCpy (buf, "?");
495     }
496     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchTraceOpenConnection failed for ti %lu, date/time %s", (unsigned long) tid, buf);
497     return conn;
498   }
499 
500 #ifdef OS_UNIX
501   if (log_query_url) {
502     str = CONN_Description (conn);
503     if (str == NULL) {
504       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for ti %lu", (unsigned long) tid);
505     } else {
506       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for ti %lu is %s", (unsigned long) tid, str);
507     }
508     MemFree (str);
509   }
510 #endif
511 
512   return conn;
513 }
514 
515 
PubSeqFetchSRAOpenConnection(CharPtr sraid)516 NLM_EXTERN CONN PubSeqFetchSRAOpenConnection (
517   CharPtr sraid
518 )
519 
520 {
521   Char     buf [40];
522   CONN     conn;
523   Char     query [80];
524 #ifdef OS_UNIX
525   CharPtr  str;
526 #endif
527 
528   if (StringHasNoText (sraid)) return NULL;
529 
530 #ifdef PUB_SEQ_FETCH_DEBUG
531   sprintf (query, "save=idf&view=1&val=gnl|SRA|%s", sraid);
532   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/viewer.fcgi",
533                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
534                              eMIME_AsnText, eENCOD_None, 0);
535 #endif
536 
537   /*
538   sprintf (query, "save=idf&view=0&val=gnl|SRA|%s", sraid);
539   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/viewer.fcgi",
540                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
541                              eMIME_AsnBinary, eENCOD_None, 0);
542   */
543 
544   sprintf (query, "val=gnl|SRA|%s", sraid);
545   conn = QUERY_OpenServiceQueryEx ("SeqFetch", query, 30, query + 12);
546 
547 #ifdef OS_UNIX
548   if (! log_query_url_set) {
549     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
550     if (StringDoesHaveText (str)) {
551       if (StringICmp (str, "TRUE") == 0) {
552         log_query_url = TRUE;
553       }
554     }
555     log_query_url_set = TRUE;
556   }
557 #endif
558 
559   if (conn == NULL) {
560     MakeDateTimeStamp (buf);
561     if (StringHasNoText (buf)) {
562       StringCpy (buf, "?");
563     }
564     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchSRAOpenConnection failed for sra %s, date/time %s", sraid, buf);
565     return conn;
566   }
567 
568 #ifdef OS_UNIX
569   if (log_query_url) {
570     str = CONN_Description (conn);
571     if (str == NULL) {
572       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for sra %s", sraid);
573     } else {
574       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for sra %s is %s", sraid, str);
575     }
576     MemFree (str);
577   }
578 #endif
579 
580   return conn;
581 }
582 
583 
584 static CharPtr girevtxt = "cmd=seqid&txt=on&seqid=fasta&val=";
585 
GiRevHistOpenConnection(BIG_ID uid,Int4 num,BIG_ID_PNTR uids)586 NLM_EXTERN CONN GiRevHistOpenConnection (
587   BIG_ID uid,
588   Int4 num,
589   BIG_ID_PNTR uids
590 )
591 
592 {
593   CONN     conn;
594   Int4     i;
595   CharPtr  query;
596   Char     tmp [40];
597 
598   if (uid > 0 && uids == NULL) {
599     uids = &uid;
600     num = 1;
601   }
602   if (uids == NULL || num < 1) return NULL;
603 
604   query = (CharPtr) MemNew (11 * num + StringLen (girevtxt) + 5);
605   if (query == NULL) return NULL;
606   /*
607   StringCpy (query, girevtxt);
608   */
609   StringCpy (query, "val=");
610 
611   for (i = 0; i < num; i++) {
612     sprintf (tmp, "%s%lld", "," + !i, (long long) uids [i]);
613     StringCat (query, tmp);
614   }
615 
616   /*
617   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/sutils/girevhist.cgi",
618                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
619                              eMIME_Plain, eENCOD_None, 0);
620   */
621 
622   if (num > 1)
623     sprintf (tmp, "%lld(%d)", (long long) *uids, (int) num);
624   else
625     StringMove (tmp, query + 4);
626 
627   conn = QUERY_OpenServiceQueryEx ("Gi2Accn", query, 30, tmp);
628 
629   MemFree (query);
630   return conn;
631 }
632 
633 
634 static CharPtr giaccvertxt = "cmd=seqid&txt=on&seqid=15&val=";
635 
GiAccVerOpenConnection(BIG_ID uid,Int4 num,BIG_ID_PNTR uids)636 NLM_EXTERN CONN GiAccVerOpenConnection (
637   BIG_ID uid,
638   Int4 num,
639   BIG_ID_PNTR uids
640 )
641 
642 {
643   CONN     conn;
644   Int4     i;
645   CharPtr  query;
646   Char     tmp [40];
647 
648   if (uid > 0 && uids == NULL) {
649     uids = &uid;
650     num = 1;
651   }
652   if (uids == NULL || num < 1) return NULL;
653 
654   query = (CharPtr) MemNew (11 * num + StringLen (giaccvertxt) + 5);
655   if (query == NULL) return NULL;
656   /*
657   StringCpy (query, giaccvertxt);
658   */
659   StringCpy (query, "val=");
660 
661   for (i = 0; i < num; i++) {
662     sprintf (tmp, "%s%lld", "," + !i, (long long) uids [i]);
663     StringCat (query, tmp);
664   }
665 
666   /*
667   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/sutils/girevhist.cgi",
668                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
669                              eMIME_Plain, eENCOD_None, 0);
670   */
671 
672   if (num > 1)
673     sprintf (tmp, "%lld(%d)", (long long) *uids, (int) num);
674   else
675     StringMove (tmp, query + 4);
676 
677   conn = QUERY_OpenServiceQueryEx ("Gi2AccVer", query, 30, tmp);
678 
679   MemFree (query);
680   return conn;
681 }
682 
683 
AccnRevHistOpenConnection(CharPtr accn)684 NLM_EXTERN CONN AccnRevHistOpenConnection (
685   CharPtr accn
686 )
687 
688 {
689   Char  query [80];
690 
691   if (StringHasNoText (accn)) return NULL;
692 
693   /*
694   sprintf (query, "save=idf&view=gi&maxplex=0&val=%s", accn);
695   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/viewer.fcgi",
696                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
697                              eMIME_Plain, eENCOD_None, 0);
698   */
699 
700   sprintf (query, "val=%s", accn);
701   return QUERY_OpenServiceQueryEx ("Accn2Gi", query, 30, query + 4);
702 }
703 
704 
GiSeqIdSetOpenConnection(BIG_ID gi)705 NLM_EXTERN CONN GiSeqIdSetOpenConnection (
706   BIG_ID gi
707 )
708 
709 {
710   Char  query [80];
711 
712   if (gi < 1) return NULL;
713 
714   /*
715   sprintf (query, "cmd=seqid&txt=on&seqid=asntext&os=PUBSEQ_OS&val=%lld", (long long) gi);
716   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/sutils/girevhist.cgi",
717                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
718                              eMIME_Plain, eENCOD_None, 0);
719   */
720 
721   sprintf (query, "val=%lld", (long long) gi);
722   return QUERY_OpenServiceQueryEx ("Gi2SeqIdSet", query, 30, query + 4);
723 }
724 
725 
726 static CharPtr accnlsttxt = "cmd=seqid&txt=on&seqid=fastalong&val=";
727 
AccnListOpenConnection(CharPtr PNTR accns)728 NLM_EXTERN CONN AccnListOpenConnection (
729   CharPtr PNTR accns
730 )
731 
732 {
733   Char     buf [40];
734   CONN     conn;
735   Int4     i;
736   size_t   len;
737   Int4     num;
738   CharPtr  query;
739   CharPtr  tmp;
740 
741   if (accns == NULL) return NULL;
742 
743   for (num = 0, len = 0; accns [num] != NULL; num++) {
744     len += StringLen (accns [num]) + 1;
745   }
746   if (num < 1) return NULL;
747 
748   query = (CharPtr) MemNew (len + StringLen (accnlsttxt) + 5);
749   if (query == NULL) return NULL;
750   tmp = query;
751 
752   /*
753   tmp = StringMove (tmp, accnlsttxt);
754   */
755   tmp = StringMove (tmp, "val=");
756 
757   tmp = StringMove (tmp, accns [0]);
758 
759   for (i = 1; accns [i] != NULL; i++) {
760     tmp = StringMove (tmp, ",");
761     tmp = StringMove (tmp, accns [i]);
762   }
763 
764   /*
765   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/entrez/sutils/girevhist.cgi",
766                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
767                              eMIME_Plain, eENCOD_None, 0);
768   */
769 
770   if (num > 1)
771     sprintf (buf, "%.20s%s(%d)", *accns, StringLen (*accns) > 20 ? "..." : "", (int) num);
772   else
773     StringNCpy_0 (buf, *accns, sizeof(buf) - 1);
774 
775   conn = QUERY_OpenServiceQueryEx ("AccnList", query, 30, buf);
776 
777   MemFree (query);
778   return conn;
779 }
780 
781 
CommonWaitForReply(CONN conn)782 static EIO_Status CommonWaitForReply (
783   CONN conn
784 )
785 
786 {
787   time_t           currtime, starttime;
788   time_t           max = 0;
789   EIO_Status       status;
790   STimeout         timeout;
791 #ifdef OS_MAC
792   EventRecord      currEvent;
793 #endif
794 
795   if (conn == NULL) return eIO_Unknown;
796 
797 #ifdef OS_MAC
798   timeout.sec = 0;
799   timeout.usec = 0;
800 #else
801   timeout.sec = 100;
802   timeout.usec = 0;
803 #endif
804 
805   starttime = GetSecs ();
806   while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) {
807     currtime = GetSecs ();
808     max = currtime - starttime;
809 #ifdef OS_MAC
810     WaitNextEvent (0, &currEvent, 0, NULL);
811 #endif
812   }
813 
814   return status;
815 }
816 
817 
PubMedReadReply(CONN conn,EIO_Status status)818 NLM_EXTERN PubmedEntryPtr PubMedReadReply (
819   CONN conn,
820   EIO_Status status
821 )
822 
823 {
824   AsnIoConnPtr    aicp;
825   PubmedEntryPtr  pep = NULL;
826 
827   if (conn != NULL && status == eIO_Success) {
828     aicp = QUERY_AsnIoConnOpen ("r", conn);
829     pep = PubmedEntryAsnRead (aicp->aip, NULL);
830     QUERY_AsnIoConnClose (aicp);
831   }
832 
833   if (pep != NULL) {
834     ChangeMedlineAuthorsToISO ((MedlineEntryPtr) pep->medent);
835   }
836 
837   return pep;
838 }
839 
840 
PubMedWaitForReply(CONN conn)841 NLM_EXTERN PubmedEntryPtr PubMedWaitForReply (
842   CONN conn
843 )
844 
845 {
846   PubmedEntryPtr  pep = NULL;
847 
848   if (conn == NULL) return NULL;
849 
850   if (CommonWaitForReply (conn) == eIO_Success) {
851     pep = PubMedReadReply (conn, eIO_Success);
852   }
853   CONN_Close (conn);
854 
855   return pep;
856 }
857 
858 
859 #define PUB_SEQ_DEBUG_TEMP_FILE "pubseqfetchtempfile"
860 
PubSeqReadReply(CONN conn,EIO_Status status)861 NLM_EXTERN SeqEntryPtr PubSeqReadReply (
862   CONN conn,
863   EIO_Status status
864 )
865 
866 {
867   AsnIoConnPtr  aicp;
868   ErrSev        oldsev;
869   SeqEntryPtr   sep = NULL;
870 #ifdef PUB_SEQ_FETCH_DEBUG
871   AsnIoPtr      aip;
872   FILE          *fp;
873 #endif
874 
875   if (conn != NULL && status == eIO_Success) {
876 #ifdef PUB_SEQ_FETCH_DEBUG
877     fp = FileOpen (PUB_SEQ_DEBUG_TEMP_FILE, "w");
878     QUERY_CopyResultsToFile (conn, fp);
879     FileClose (fp);
880     aip = AsnIoOpen (PUB_SEQ_DEBUG_TEMP_FILE, "r");
881     sep = SeqEntryAsnRead (aip, NULL);
882     AsnIoClose (aip);
883     if (sep != NULL) {
884       FileRemove (PUB_SEQ_DEBUG_TEMP_FILE);
885     }
886 #else
887     oldsev = ErrSetMessageLevel (SEV_MAX);
888     aicp = QUERY_AsnIoConnOpen ("rb", conn);
889     sep = SeqEntryAsnRead (aicp->aip, NULL);
890     QUERY_AsnIoConnClose (aicp);
891     ErrSetMessageLevel (oldsev);
892 #endif
893   }
894   return sep;
895 }
896 
897 
PubSeqWaitForReply(CONN conn)898 NLM_EXTERN SeqEntryPtr PubSeqWaitForReply (
899   CONN conn
900 )
901 
902 {
903   SeqEntryPtr  sep = NULL;
904   EIO_Status   status;
905 #ifdef OS_UNIX
906   CharPtr      str;
907 #endif
908 
909   if (conn == NULL) return NULL;
910 
911 #ifdef OS_UNIX
912   if (! log_query_url_set) {
913     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
914     if (StringDoesHaveText (str)) {
915       if (StringICmp (str, "TRUE") == 0) {
916         log_query_url = TRUE;
917       }
918     }
919     log_query_url_set = TRUE;
920   }
921 #endif
922 
923   status = CommonWaitForReply (conn);
924   if (status == eIO_Success) {
925     sep = PubSeqReadReply (conn, eIO_Success);
926 #ifdef OS_UNIX
927     /*
928     if (sep == NULL) {
929       ErrPostEx (SEV_ERROR, 0, 0, "PubSeqWaitForReply unable to read valid result");
930     }
931     */
932   } else {
933     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqWaitForReply failed with status %d", (int) status);
934 #endif
935   }
936   CONN_Close (conn);
937 
938   return sep;
939 }
940 
941 
GiRevHistReadReply(CONN conn,EIO_Status status)942 NLM_EXTERN CharPtr GiRevHistReadReply (
943   CONN conn,
944   EIO_Status status
945 )
946 
947 {
948   AsnIoConnPtr  aicp;
949   ByteStorePtr  bsp;
950   Char          buf [512];
951   size_t        n_read;
952   CharPtr       str = NULL;
953 
954   if (conn != NULL && status == eIO_Success) {
955     bsp = BSNew (512);
956     aicp = QUERY_AsnIoConnOpen ("r", conn);
957     while ((status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain)) == eIO_Success) {
958       BSWrite (bsp, buf, n_read);
959     }
960     str = BSMerge (bsp, NULL);
961     BSFree (bsp);
962     QUERY_AsnIoConnClose (aicp);
963   }
964   return str;
965 }
966 
967 
GiRevHistWaitForReply(CONN conn)968 NLM_EXTERN CharPtr GiRevHistWaitForReply (
969   CONN conn
970 )
971 
972 {
973   CharPtr  str = NULL;
974 
975   if (conn == NULL) return NULL;
976 
977   if (CommonWaitForReply (conn) == eIO_Success) {
978     str = GiRevHistReadReply (conn, eIO_Success);
979   }
980   CONN_Close (conn);
981 
982   return str;
983 }
984 
985 
GiAccVerReadReply(CONN conn,EIO_Status status)986 NLM_EXTERN CharPtr GiAccVerReadReply (
987   CONN conn,
988   EIO_Status status
989 )
990 
991 {
992   AsnIoConnPtr  aicp;
993   ByteStorePtr  bsp;
994   Char          buf [512];
995   size_t        n_read;
996   CharPtr       str = NULL;
997 
998   if (conn != NULL && status == eIO_Success) {
999     bsp = BSNew (512);
1000     aicp = QUERY_AsnIoConnOpen ("r", conn);
1001     while ((status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain)) == eIO_Success) {
1002       BSWrite (bsp, buf, n_read);
1003     }
1004     str = BSMerge (bsp, NULL);
1005     BSFree (bsp);
1006     QUERY_AsnIoConnClose (aicp);
1007   }
1008   return str;
1009 }
1010 
1011 
GiAccVerWaitForReply(CONN conn)1012 NLM_EXTERN CharPtr GiAccVerWaitForReply (
1013   CONN conn
1014 )
1015 
1016 {
1017   CharPtr  str = NULL;
1018 
1019   if (conn == NULL) return NULL;
1020 
1021   if (CommonWaitForReply (conn) == eIO_Success) {
1022     str = GiAccVerReadReply (conn, eIO_Success);
1023   }
1024   CONN_Close (conn);
1025 
1026   return str;
1027 }
1028 
1029 
AccnRevHistReadReply(CONN conn,EIO_Status status)1030 NLM_EXTERN BIG_ID AccnRevHistReadReply (
1031   CONN conn,
1032   EIO_Status status
1033 )
1034 
1035 {
1036   AsnIoConnPtr  aicp;
1037   Char          buf [32];
1038   Char          ch;
1039   BIG_ID        gi = 0;
1040   size_t        n_read;
1041   CharPtr       ptr;
1042   long long     val;
1043 
1044   if (conn != NULL && status == eIO_Success) {
1045     aicp = QUERY_AsnIoConnOpen ("r", conn);
1046     status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain);
1047     if (status == eIO_Success) {
1048       ptr = buf;
1049       ch = *ptr;
1050       while (ch != '\0' && ch != '\n' && ch != '\r') {
1051          ptr++;
1052          ch = *ptr;
1053       }
1054       *ptr = '\0';
1055       if (sscanf (buf, "%lld", &val) == 1 && val > 0) {
1056         gi = val;
1057       }
1058     }
1059     QUERY_AsnIoConnClose (aicp);
1060   }
1061   return gi;
1062 }
1063 
1064 
AccnRevHistWaitForReply(CONN conn)1065 NLM_EXTERN BIG_ID AccnRevHistWaitForReply (
1066   CONN conn
1067 )
1068 
1069 {
1070     BIG_ID gi = 0;
1071 
1072   if (conn == NULL) return 0;
1073 
1074   if (CommonWaitForReply (conn) == eIO_Success) {
1075     gi = AccnRevHistReadReply (conn, eIO_Success);
1076   }
1077   CONN_Close (conn);
1078 
1079   return gi;
1080 }
1081 
1082 
GiSeqIdSetReadReply(CONN conn,EIO_Status status)1083 NLM_EXTERN SeqIdPtr GiSeqIdSetReadReply (
1084   CONN conn,
1085   EIO_Status status
1086 )
1087 
1088 {
1089   AsnIoConnPtr  aicp;
1090   SeqIdPtr      last = NULL;
1091   ErrSev        sev;
1092   SeqIdPtr      sid;
1093   SeqIdPtr      sip = NULL;
1094 
1095   if (conn != NULL && status == eIO_Success) {
1096     aicp = QUERY_AsnIoConnOpen ("r", conn);
1097     sev = ErrSetLogLevel (SEV_WARNING);
1098     while ((sid = SeqIdAsnRead (aicp->aip, NULL)) != NULL) {
1099       if (sip == NULL) {
1100         sip = sid;
1101       } else if (last != NULL) {
1102         last->next = sid;
1103       }
1104       last = sid;
1105     }
1106     ErrSetLogLevel (sev);
1107     QUERY_AsnIoConnClose (aicp);
1108   }
1109   return sip;
1110 }
1111 
1112 
GiSeqIdSetWaitForReply(CONN conn)1113 NLM_EXTERN SeqIdPtr GiSeqIdSetWaitForReply (
1114   CONN conn
1115 )
1116 
1117 {
1118   SeqIdPtr  sip = NULL;
1119 
1120   if (conn == NULL) return NULL;
1121 
1122   if (CommonWaitForReply (conn) == eIO_Success) {
1123     sip = GiSeqIdSetReadReply (conn, eIO_Success);
1124   }
1125   CONN_Close (conn);
1126 
1127   return sip;
1128 }
1129 
1130 
AccnListReadReply(CONN conn,EIO_Status status)1131 NLM_EXTERN CharPtr AccnListReadReply (
1132   CONN conn,
1133   EIO_Status status
1134 )
1135 
1136 {
1137   AsnIoConnPtr  aicp;
1138   ByteStorePtr  bsp;
1139   Char          buf [512];
1140   size_t        n_read;
1141   CharPtr       str = NULL;
1142 
1143   if (conn != NULL && status == eIO_Success) {
1144     bsp = BSNew (512);
1145     aicp = QUERY_AsnIoConnOpen ("r", conn);
1146     while ((status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain)) == eIO_Success) {
1147       BSWrite (bsp, buf, n_read);
1148     }
1149     str = BSMerge (bsp, NULL);
1150     BSFree (bsp);
1151     QUERY_AsnIoConnClose (aicp);
1152   }
1153   return str;
1154 }
1155 
1156 
AccnListWaitForReply(CONN conn)1157 NLM_EXTERN CharPtr AccnListWaitForReply (
1158   CONN conn
1159 )
1160 
1161 {
1162   CharPtr  str = NULL;
1163 
1164   if (conn == NULL) return NULL;
1165 
1166   if (CommonWaitForReply (conn) == eIO_Success) {
1167     str = AccnListReadReply (conn, eIO_Success);
1168   }
1169   CONN_Close (conn);
1170 
1171   return str;
1172 }
1173 
1174 
1175 static Boolean log_sync_query_times = FALSE;
1176 static Boolean log_sync_query_set = FALSE;
1177 
1178 
PubMedSynchronousQuery(Int4 uid)1179 NLM_EXTERN PubmedEntryPtr PubMedSynchronousQuery (
1180   Int4 uid
1181 )
1182 
1183 {
1184   CONN            conn;
1185   PubmedEntryPtr  pep;
1186 #ifdef OS_UNIX
1187   clock_t         starttime;
1188   clock_t         stoptime;
1189   CharPtr         str;
1190   struct tms      timebuf;
1191 #endif
1192 
1193   if (uid < 1) return NULL;
1194 
1195 #ifdef OS_UNIX
1196   if (! log_sync_query_set) {
1197     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1198     if (StringDoesHaveText (str)) {
1199       if (StringICmp (str, "TRUE") == 0) {
1200         log_sync_query_times = TRUE;
1201       }
1202     }
1203     log_sync_query_set = TRUE;
1204   }
1205 #endif
1206 
1207   conn = PubMedFetchOpenConnection (uid);
1208 
1209   if (conn == NULL) return NULL;
1210 
1211   QUERY_SendQuery (conn);
1212 
1213 #ifdef OS_UNIX
1214   if (log_sync_query_times) {
1215     starttime = times (&timebuf);
1216   }
1217 #endif
1218 
1219   pep = PubMedWaitForReply (conn);
1220 
1221 #ifdef OS_UNIX
1222   if (log_sync_query_times) {
1223     stoptime = times (&timebuf);
1224     printf ("PubMedWaitForReply %ld\n", (long) (stoptime - starttime));
1225   }
1226 #endif
1227 
1228   return pep;
1229 }
1230 
1231 
1232 typedef struct psconfirm {
1233   Int4     uid;
1234   Uint4    tid;
1235   CharPtr  sid;
1236   SeqIdPtr ssid;
1237   BIG_ID   gi;
1238   Uint4    ti;
1239   CharPtr  si;
1240   SeqIdPtr ssi;
1241   CharPtr  str;
1242   Boolean  found;
1243 } PsConfirm, PNTR PsConfirmPtr;
1244 
1245 
InitPsConfirm(PsConfirmPtr p)1246 static void InitPsConfirm (PsConfirmPtr p)
1247 
1248 {
1249   if (p != NULL) {
1250     p->uid = 0;
1251     p->tid = 0;
1252     p->sid = NULL;
1253     p->gi = 0;
1254     p->ti = 0;
1255     p->si = NULL;
1256     p->ssid = NULL;
1257     p->ssi = NULL;
1258     p->str = NULL;
1259     p->found = FALSE;
1260   }
1261 }
1262 
1263 
ConfirmGiInSep(BioseqPtr bsp,Pointer userdata)1264 static void ConfirmGiInSep (
1265   BioseqPtr bsp,
1266   Pointer userdata
1267 )
1268 
1269 {
1270   BIG_ID         gi;
1271   PsConfirmPtr  psp;
1272   SeqIdPtr      sip;
1273 
1274   if (bsp == NULL || userdata == NULL) return;
1275   psp = (PsConfirmPtr) userdata;
1276   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1277     if (sip->choice != SEQID_GI) continue;
1278     gi = (BIG_ID) sip->data.intvalue;
1279     if (psp->gi == 0 || gi == psp->uid) {
1280       psp->gi = gi;
1281     }
1282   }
1283 }
1284 
1285 
ConfirmAccStrInSep(BioseqPtr bsp,Pointer userdata)1286 static void ConfirmAccStrInSep (
1287   BioseqPtr bsp,
1288   Pointer userdata
1289 )
1290 
1291 {
1292   Char          buf [64];
1293   PsConfirmPtr  psp;
1294   SeqIdPtr      sip, tmp;
1295   Uint1         cmp;
1296 
1297   if (bsp == NULL || userdata == NULL) return;
1298   psp = (PsConfirmPtr) userdata;
1299   if (psp->found) return;
1300   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1301     tmp = SeqIdStripLocus (SeqIdDup (sip));
1302     SeqIdWrite (bsp->id, buf, PRINTID_TEXTID_ACC_ONLY, sizeof (buf) - 1);
1303     if (StringICmp (psp->str, buf) == 0) {
1304       psp->found = TRUE;
1305       return;
1306     }
1307     cmp = SeqIdComp (tmp, psp->ssid);
1308     if (cmp == SIC_YES) {
1309       psp->ssi = sip;
1310     } else if (psp->ssi == NULL && cmp == SIC_DIFF) {
1311       psp->ssi = sip;
1312     }
1313   }
1314   SeqIdFree (tmp);
1315 }
1316 
1317 
ConfirmTiInSep(BioseqPtr bsp,Pointer userdata)1318 static void ConfirmTiInSep (
1319   BioseqPtr bsp,
1320   Pointer userdata
1321 )
1322 
1323 {
1324   Uint4          ti;
1325   PsConfirmPtr  psp;
1326   SeqIdPtr      sip;
1327   DbtagPtr      dbtag;
1328 
1329   if (bsp == NULL || userdata == NULL) return;
1330   psp = (PsConfirmPtr) userdata;
1331   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1332     if (sip->choice != SEQID_GENERAL) continue;
1333     dbtag = (DbtagPtr) sip->data.ptrvalue;
1334     if (dbtag == NULL || StringCmp (dbtag->db, "ti") != 0 || dbtag->tag == NULL) continue;
1335     if (dbtag->tag->str == NULL && (Uint4) dbtag->tag->id > 0) {
1336       ti = (Uint4) dbtag->tag->id;
1337       if (psp->ti == 0 || ti == psp->tid) {
1338         psp->ti = ti;
1339       }
1340     }
1341   }
1342 }
1343 
1344 
ConfirmSraidInSep(BioseqPtr bsp,Pointer userdata)1345 static void ConfirmSraidInSep (
1346   BioseqPtr bsp,
1347   Pointer userdata
1348 )
1349 
1350 {
1351   PsConfirmPtr  psp;
1352   SeqIdPtr      sip;
1353   CharPtr       sraid;
1354   DbtagPtr      dbtag;
1355 
1356   if (bsp == NULL || userdata == NULL) return;
1357   psp = (PsConfirmPtr) userdata;
1358   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1359     if (sip->choice != SEQID_GENERAL) continue;
1360     dbtag = (DbtagPtr) sip->data.ptrvalue;
1361     if (dbtag == NULL || StringCmp (dbtag->db, "SRA") != 0 || dbtag->tag == NULL) continue;
1362     if (dbtag->tag->str != NULL) {
1363       sraid = dbtag->tag->str;
1364       if (psp->si == NULL || StringCmp (sraid, psp->si) == 0) {
1365         psp->si = sraid;
1366       }
1367     }
1368   }
1369 }
1370 
1371 
VerifyGIInSeqEntry(BIG_ID uid,SeqEntryPtr sep)1372 static void VerifyGIInSeqEntry (
1373   BIG_ID uid,
1374   SeqEntryPtr sep
1375 )
1376 
1377 {
1378   PsConfirm    ps;
1379 
1380   InitPsConfirm (&ps);
1381   ps.uid = uid;
1382   VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmGiInSep);
1383   if (ps.gi != uid) {
1384     ErrPostEx (SEV_ERROR, 0, 0,
1385                "PubSeqSynchronousQuery requested gi %lld but received gi %lld",
1386                (long long) uid, (long long) ps.gi);
1387   }
1388 }
1389 
1390 
VerifyAccStrInSeqEntry(CharPtr id_str,SeqEntryPtr sep)1391 static void VerifyAccStrInSeqEntry (
1392   CharPtr id_str,
1393   SeqEntryPtr sep
1394 )
1395 
1396 {
1397   PsConfirm    ps;
1398   Char         id_buf[PATH_MAX];
1399   CharPtr      ptr;
1400 
1401   InitPsConfirm (&ps);
1402   ps.str = StringSaveNoNull (id_str);
1403   ptr = StringChr (ps.str, '.');
1404   if (ptr != NULL) {
1405     *ptr = '\0';
1406   }
1407   ps.ssid = MakeSeqID (id_str);
1408 
1409   VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmAccStrInSep);
1410   if ((! ps.found) && SeqIdComp (ps.ssid, ps.ssi) != SIC_YES) {
1411     SeqIdWrite (ps.ssi, id_buf, PRINTID_FASTA_SHORT, sizeof (id_buf) - 1);
1412     ErrPostEx (SEV_ERROR, 0, 0,
1413                "PubSeqSynchronousQuery requested %s but received %s",
1414                  id_str, id_buf);
1415   }
1416   ps.ssid = SeqIdFree (ps.ssid);
1417   ps.str = MemFree (ps.str);
1418 }
1419 
1420 
PubSeqSynchronousQueryEx(Int4 uid,Int2 retcode,Int4 flags,CharPtr id_str)1421 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQueryEx (
1422   Int4 uid,
1423   Int2 retcode,
1424   Int4 flags,
1425   CharPtr id_str
1426 )
1427 
1428 {
1429   Char         buf [32];
1430   CONN         conn;
1431   SeqEntryPtr  sep;
1432   CharPtr      str = NULL;
1433 #ifdef OS_UNIX
1434   clock_t      starttime;
1435   clock_t      stoptime;
1436   struct tms   timebuf;
1437 #endif
1438 
1439   if (uid < 1 && StringHasNoText (id_str)) return NULL;
1440 
1441 #ifdef OS_UNIX
1442   if (! log_sync_query_set) {
1443     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1444     if (StringDoesHaveText (str)) {
1445       if (StringICmp (str, "TRUE") == 0) {
1446         log_sync_query_times = TRUE;
1447       }
1448     }
1449     log_sync_query_set = TRUE;
1450   }
1451 #endif
1452 
1453   if (StringHasNoText (id_str)) {
1454     conn = PubSeqFetchOpenConnection (uid, retcode, flags);
1455   } else {
1456     conn = PubSeqFetchOpenConnectionString (id_str, retcode, flags);
1457   }
1458 
1459   if (conn == NULL) return NULL;
1460 
1461   QUERY_SendQuery (conn);
1462 
1463 #ifdef OS_UNIX
1464   if (log_sync_query_times) {
1465     starttime = times (&timebuf);
1466   }
1467 #endif
1468 
1469   str = CONN_Description (conn);
1470   if (StringHasNoText (str)) {
1471     str = StringSave ("?");
1472   }
1473 
1474   sep = PubSeqWaitForReply (conn);
1475 
1476 #ifdef OS_UNIX
1477   if (log_sync_query_times) {
1478     stoptime = times (&timebuf);
1479     printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
1480   }
1481 #endif
1482 
1483   if (sep != NULL) {
1484     if (uid > 0) {
1485       VerifyGIInSeqEntry (uid, sep);
1486     } else {
1487       VerifyAccStrInSeqEntry (id_str, sep);
1488     }
1489   } else {
1490     MakeDateTimeStamp (buf);
1491     if (StringHasNoText (buf)) {
1492       StringCpy (buf, "?");
1493     }
1494     if (uid > 0) {
1495       ErrPostEx (SEV_ERROR, 0, 0,
1496                  "PubSeqSynchronousQuery failed for gi %lld, date/time %s, URL is %s",
1497                  (long long) uid, buf, str);
1498     } else {
1499       ErrPostEx (SEV_ERROR, 0, 0,
1500                  "PubSeqSynchronousQuery failed for accession %s, date/time %s, URL is %s",
1501                  id_str, buf, str);
1502     }
1503   }
1504 
1505   MemFree (str);
1506 
1507   return sep;
1508 }
1509 
1510 
PubSeqSynchronousQuery(Int4 uid,Int2 retcode,Int4 flags)1511 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQuery (
1512   Int4 uid,
1513   Int2 retcode,
1514   Int4 flags
1515 )
1516 
1517 {
1518   return PubSeqSynchronousQueryEx (uid, retcode, flags, NULL);
1519 }
1520 
1521 
PubSeqSynchronousQueryId(SeqIdPtr sip,Int2 retcode,Int4 flags)1522 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQueryId (
1523   SeqIdPtr sip,
1524   Int2 retcode,
1525   Int4 flags
1526 )
1527 
1528 {
1529   Int4 uid;
1530   Char id_buf[PATH_MAX];
1531 
1532   if (sip == NULL) {
1533     return NULL;
1534   } else if (sip->choice == SEQID_GI) {
1535     return PubSeqSynchronousQueryEx (sip->data.intvalue, retcode, flags, NULL);
1536   } else if (sip->choice != SEQID_LOCAL) {
1537     uid = GetGIForSeqId (sip);
1538     if (uid > 0) {
1539       return PubSeqSynchronousQueryEx (uid, retcode, flags, NULL);
1540     } else {
1541       SeqIdWrite (sip, id_buf, PRINTID_FASTA_SHORT, sizeof (id_buf) - 1);
1542       return PubSeqSynchronousQueryEx (0, retcode, flags, id_buf);
1543     }
1544   } else {
1545     return NULL;
1546   }
1547 }
1548 
1549 
SeqIdFromPubSeqString(CharPtr str)1550 NLM_EXTERN SeqIdPtr SeqIdFromPubSeqString (CharPtr str)
1551 
1552 {
1553   Boolean alldigits = TRUE;
1554   CharPtr ptr;
1555   Char    ch;
1556   BIG_ID  uid = 0;
1557   long long val;
1558   SeqIdPtr sip = NULL;
1559 
1560   if (StringHasNoText (str)) {
1561     return NULL;
1562   }
1563   ptr = str;
1564   ch = *ptr;
1565   while (ch != '\0') {
1566     if (! IS_DIGIT (ch)) {
1567       alldigits = FALSE;
1568     }
1569     ptr++;
1570     ch = *ptr;
1571   }
1572 
1573   if (alldigits) {
1574     if (sscanf (str, "%lld", &val) == 1) {
1575       uid = (BIG_ID) val;
1576       sip = ValNodeNew (NULL);
1577       sip->choice = SEQID_GI;
1578       sip->data.intvalue = uid;
1579     }
1580   } else if (StringChr (str, '|') == NULL) {
1581     sip = SeqIdFromAccessionDotVersion (str);
1582   } else {
1583     sip = MakeSeqID (str);
1584   }
1585   return sip;
1586 }
1587 
1588 
PubSeqSynchronousQueryString(CharPtr str,Int2 retcode,Int4 flags)1589 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQueryString (
1590   CharPtr str,
1591   Int2 retcode,
1592   Int4 flags
1593 )
1594 
1595 {
1596   SeqIdPtr sip;
1597   SeqEntryPtr sep = NULL;
1598 
1599   if (StringHasNoText (str)) {
1600     return NULL;
1601   }
1602   sip = SeqIdFromPubSeqString (str);
1603   sep = PubSeqSynchronousQueryId (sip, retcode, flags);
1604   sip = SeqIdFree (sip);
1605   return sep;
1606 }
1607 
1608 
PubSeqSynchronousQueryTI(Uint4 tid,Int2 retcode,Int4 flags)1609 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQueryTI (
1610   Uint4 tid,
1611   Int2 retcode,
1612   Int4 flags
1613 )
1614 
1615 {
1616   Char         buf [32];
1617   CONN         conn;
1618   PsConfirm    ps;
1619   SeqEntryPtr  sep;
1620   CharPtr      str = NULL;
1621 #ifdef OS_UNIX
1622   clock_t      starttime;
1623   clock_t      stoptime;
1624   struct tms   timebuf;
1625 #endif
1626 
1627   if (tid < 1) return NULL;
1628 
1629 #ifdef OS_UNIX
1630   if (! log_sync_query_set) {
1631     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1632     if (StringDoesHaveText (str)) {
1633       if (StringICmp (str, "TRUE") == 0) {
1634         log_sync_query_times = TRUE;
1635       }
1636     }
1637     log_sync_query_set = TRUE;
1638   }
1639 #endif
1640 
1641   conn = PubSeqFetchTraceOpenConnection (tid, retcode, flags);
1642 
1643   if (conn == NULL) return NULL;
1644 
1645   QUERY_SendQuery (conn);
1646 
1647 #ifdef OS_UNIX
1648   if (log_sync_query_times) {
1649     starttime = times (&timebuf);
1650   }
1651 #endif
1652 
1653   str = CONN_Description (conn);
1654   if (StringHasNoText (str)) {
1655     str = StringSave ("?");
1656   }
1657 
1658   sep = PubSeqWaitForReply (conn);
1659 
1660 #ifdef OS_UNIX
1661   if (log_sync_query_times) {
1662     stoptime = times (&timebuf);
1663     printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
1664   }
1665 #endif
1666 
1667   if (sep != NULL) {
1668     InitPsConfirm (&ps);
1669     ps.tid = tid;
1670     VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmTiInSep);
1671     if (ps.ti != tid) {
1672       ErrPostEx (SEV_ERROR, 0, 0,
1673                  "PubSeqSynchronousQueryTI requested ti %lu but received ti %lu",
1674                  (long) tid, (long) ps.ti);
1675     }
1676   } else {
1677     MakeDateTimeStamp (buf);
1678     if (StringHasNoText (buf)) {
1679       StringCpy (buf, "?");
1680     }
1681     ErrPostEx (SEV_ERROR, 0, 0,
1682                "PubSeqSynchronousQueryTI failed for ti %lu, date/time %s, URL is %s",
1683                (long) tid, buf, str);
1684   }
1685 
1686   MemFree (str);
1687 
1688   return sep;
1689 }
1690 
1691 
PubSeqSynchronousQuerySRA(CharPtr sraid)1692 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQuerySRA (
1693   CharPtr sraid
1694 )
1695 
1696 {
1697   Char         buf [32];
1698   CONN         conn;
1699   PsConfirm    ps;
1700   SeqEntryPtr  sep;
1701   CharPtr      str = NULL;
1702 #ifdef OS_UNIX
1703   clock_t      starttime;
1704   clock_t      stoptime;
1705   struct tms   timebuf;
1706 #endif
1707 
1708   if (StringHasNoText (sraid)) return NULL;
1709 
1710 #ifdef OS_UNIX
1711   if (! log_sync_query_set) {
1712     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1713     if (StringDoesHaveText (str)) {
1714       if (StringICmp (str, "TRUE") == 0) {
1715         log_sync_query_times = TRUE;
1716       }
1717     }
1718     log_sync_query_set = TRUE;
1719   }
1720 #endif
1721 
1722   conn = PubSeqFetchSRAOpenConnection (sraid);
1723 
1724   if (conn == NULL) return NULL;
1725 
1726   QUERY_SendQuery (conn);
1727 
1728 #ifdef OS_UNIX
1729   if (log_sync_query_times) {
1730     starttime = times (&timebuf);
1731   }
1732 #endif
1733 
1734   str = CONN_Description (conn);
1735   if (StringHasNoText (str)) {
1736     str = StringSave ("?");
1737   }
1738 
1739   sep = PubSeqWaitForReply (conn);
1740 
1741 #ifdef OS_UNIX
1742   if (log_sync_query_times) {
1743     stoptime = times (&timebuf);
1744     printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
1745   }
1746 #endif
1747 
1748   if (sep != NULL) {
1749     InitPsConfirm (&ps);
1750     ps.sid = sraid;
1751     VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmSraidInSep);
1752     if (StringCmp (ps.si, sraid) != 0) {
1753       ErrPostEx (SEV_ERROR, 0, 0,
1754                  "PubSeqSynchronousQuerySRA requested sra %s but received sra %s",
1755                  sraid, ps.si);
1756     }
1757   } else {
1758     MakeDateTimeStamp (buf);
1759     if (StringHasNoText (buf)) {
1760       StringCpy (buf, "?");
1761     }
1762     ErrPostEx (SEV_ERROR, 0, 0,
1763                "PubSeqSynchronousQuerySRA failed for sra %s, date/time %s, URL is %s",
1764                sraid, buf, str);
1765   }
1766 
1767   MemFree (str);
1768 
1769   return sep;
1770 }
1771 
1772 
GiRevHistSynchronousQuery(BIG_ID uid,Int4 num,BIG_ID_PNTR uids)1773 NLM_EXTERN CharPtr GiRevHistSynchronousQuery (
1774   BIG_ID uid,
1775   Int4 num,
1776   BIG_ID_PNTR uids
1777 )
1778 
1779 {
1780   CONN        conn;
1781   CharPtr     str;
1782 #ifdef OS_UNIX
1783   clock_t     starttime;
1784   clock_t     stoptime;
1785   struct tms  timebuf;
1786 #endif
1787 
1788 #ifdef OS_UNIX
1789   if (! log_sync_query_set) {
1790     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1791     if (StringDoesHaveText (str)) {
1792       if (StringICmp (str, "TRUE") == 0) {
1793         log_sync_query_times = TRUE;
1794       }
1795     }
1796     log_sync_query_set = TRUE;
1797   }
1798 #endif
1799 
1800   conn = GiRevHistOpenConnection (uid, num, uids);
1801 
1802   if (conn == NULL) return NULL;
1803 
1804   QUERY_SendQuery (conn);
1805 
1806 #ifdef OS_UNIX
1807   if (log_sync_query_times) {
1808     starttime = times (&timebuf);
1809   }
1810 #endif
1811 
1812   str = GiRevHistWaitForReply (conn);
1813 
1814 #ifdef OS_UNIX
1815   if (log_sync_query_times) {
1816     stoptime = times (&timebuf);
1817     printf ("GiRevHistWaitForReply %ld\n", (long) (stoptime - starttime));
1818   }
1819 #endif
1820 
1821   return str;
1822 }
1823 
1824 
GiAccVerSynchronousQuery(BIG_ID uid,Int4 num,BIG_ID_PNTR uids)1825 NLM_EXTERN CharPtr GiAccVerSynchronousQuery (
1826   BIG_ID uid,
1827   Int4 num,
1828   BIG_ID_PNTR uids
1829 )
1830 
1831 {
1832   CONN        conn;
1833   CharPtr     str;
1834 #ifdef OS_UNIX
1835   clock_t     starttime;
1836   clock_t     stoptime;
1837   struct tms  timebuf;
1838 #endif
1839 
1840 #ifdef OS_UNIX
1841   if (! log_sync_query_set) {
1842     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1843     if (StringDoesHaveText (str)) {
1844       if (StringICmp (str, "TRUE") == 0) {
1845         log_sync_query_times = TRUE;
1846       }
1847     }
1848     log_sync_query_set = TRUE;
1849   }
1850 #endif
1851 
1852   conn = GiAccVerOpenConnection (uid, num, uids);
1853 
1854   if (conn == NULL) return NULL;
1855 
1856   QUERY_SendQuery (conn);
1857 
1858 #ifdef OS_UNIX
1859   if (log_sync_query_times) {
1860     starttime = times (&timebuf);
1861   }
1862 #endif
1863 
1864   str = GiAccVerWaitForReply (conn);
1865 
1866 #ifdef OS_UNIX
1867   if (log_sync_query_times) {
1868     stoptime = times (&timebuf);
1869     printf ("GiAccVerWaitForReply %ld\n", (long) (stoptime - starttime));
1870   }
1871 #endif
1872 
1873   return str;
1874 }
1875 
1876 
AccnRevHistSynchronousQuery(CharPtr accn)1877 NLM_EXTERN BIG_ID AccnRevHistSynchronousQuery (
1878   CharPtr accn
1879 )
1880 
1881 {
1882   CONN        conn;
1883   BIG_ID        gi;
1884 #ifdef OS_UNIX
1885   clock_t     starttime;
1886   clock_t     stoptime;
1887   CharPtr     str;
1888   struct tms  timebuf;
1889 #endif
1890 
1891 #ifdef OS_UNIX
1892   if (! log_sync_query_set) {
1893     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1894     if (StringDoesHaveText (str)) {
1895       if (StringICmp (str, "TRUE") == 0) {
1896         log_sync_query_times = TRUE;
1897       }
1898     }
1899     log_sync_query_set = TRUE;
1900   }
1901 #endif
1902 
1903   conn = AccnRevHistOpenConnection (accn);
1904 
1905   if (conn == NULL) return 0;
1906 
1907   QUERY_SendQuery (conn);
1908 
1909 #ifdef OS_UNIX
1910   if (log_sync_query_times) {
1911     starttime = times (&timebuf);
1912   }
1913 #endif
1914 
1915   gi = AccnRevHistWaitForReply (conn);
1916 
1917 #ifdef OS_UNIX
1918   if (log_sync_query_times) {
1919     stoptime = times (&timebuf);
1920     printf ("AccnRevHistWaitForReply %ld\n", (long) (stoptime - starttime));
1921   }
1922 #endif
1923 
1924   return gi;
1925 }
1926 
1927 
GiSeqIdSetSynchronousQuery(BIG_ID gi)1928 NLM_EXTERN SeqIdPtr GiSeqIdSetSynchronousQuery (
1929   BIG_ID gi
1930 )
1931 
1932 {
1933   CONN        conn;
1934   SeqIdPtr    sip;
1935 #ifdef OS_UNIX
1936   clock_t     starttime;
1937   clock_t     stoptime;
1938   CharPtr     str;
1939   struct tms  timebuf;
1940 #endif
1941 
1942 #ifdef OS_UNIX
1943   if (! log_sync_query_set) {
1944     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1945     if (StringDoesHaveText (str)) {
1946       if (StringICmp (str, "TRUE") == 0) {
1947         log_sync_query_times = TRUE;
1948       }
1949     }
1950     log_sync_query_set = TRUE;
1951   }
1952 #endif
1953 
1954   conn = GiSeqIdSetOpenConnection (gi);
1955 
1956   if (conn == NULL) return NULL;
1957 
1958   QUERY_SendQuery (conn);
1959 
1960 #ifdef OS_UNIX
1961   if (log_sync_query_times) {
1962     starttime = times (&timebuf);
1963   }
1964 #endif
1965 
1966   sip = GiSeqIdSetWaitForReply (conn);
1967 
1968 #ifdef OS_UNIX
1969   if (log_sync_query_times) {
1970     stoptime = times (&timebuf);
1971     printf ("GiSeqIdSetWaitForReply %ld\n", (long) (stoptime - starttime));
1972   }
1973 #endif
1974 
1975   return sip;
1976 }
1977 
1978 
AccnListSynchronousQuery(CharPtr PNTR accns)1979 NLM_EXTERN CharPtr AccnListSynchronousQuery (
1980   CharPtr PNTR accns
1981 )
1982 
1983 {
1984   CONN        conn;
1985   CharPtr     str;
1986 #ifdef OS_UNIX
1987   clock_t     starttime;
1988   clock_t     stoptime;
1989   struct tms  timebuf;
1990 #endif
1991 
1992 #ifdef OS_UNIX
1993   if (! log_sync_query_set) {
1994     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1995     if (StringDoesHaveText (str)) {
1996       if (StringICmp (str, "TRUE") == 0) {
1997         log_sync_query_times = TRUE;
1998       }
1999     }
2000     log_sync_query_set = TRUE;
2001   }
2002 #endif
2003 
2004   conn = AccnListOpenConnection (accns);
2005 
2006   if (conn == NULL) return NULL;
2007 
2008   QUERY_SendQuery (conn);
2009 
2010 #ifdef OS_UNIX
2011   if (log_sync_query_times) {
2012     starttime = times (&timebuf);
2013   }
2014 #endif
2015 
2016   str = AccnListWaitForReply (conn);
2017 
2018 #ifdef OS_UNIX
2019   if (log_sync_query_times) {
2020     stoptime = times (&timebuf);
2021     printf ("AccnListWaitForReply %ld\n", (long) (stoptime - starttime));
2022   }
2023 #endif
2024 
2025   return str;
2026 }
2027 
2028 
PubMedAsynchronousQuery(Int4 uid,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2029 NLM_EXTERN Boolean PubMedAsynchronousQuery (
2030   Int4 uid,
2031   QUEUE* queue,
2032   QueryResultProc resultproc,
2033   VoidPtr userdata
2034 )
2035 
2036 {
2037   CONN  conn;
2038 
2039   conn = PubMedFetchOpenConnection (uid);
2040 
2041   if (conn == NULL) return FALSE;
2042 
2043   QUERY_SendQuery (conn);
2044 
2045   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2046 
2047   return TRUE;
2048 }
2049 
2050 
PubMedCheckQueue(QUEUE * queue)2051 NLM_EXTERN Int4 PubMedCheckQueue (
2052   QUEUE* queue
2053 )
2054 
2055 {
2056   return QUERY_CheckQueue (queue);
2057 }
2058 
2059 
PubSeqAsynchronousQuery(Int4 uid,Int2 retcode,Int4 flags,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2060 NLM_EXTERN Boolean PubSeqAsynchronousQuery (
2061   Int4 uid,
2062   Int2 retcode,
2063   Int4 flags,
2064   QUEUE* queue,
2065   QueryResultProc resultproc,
2066   VoidPtr userdata
2067 )
2068 
2069 {
2070   CONN  conn;
2071 
2072   conn = PubSeqFetchOpenConnection (uid, retcode, flags);
2073 
2074   if (conn == NULL) return FALSE;
2075 
2076   QUERY_SendQuery (conn);
2077 
2078   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2079 
2080   return TRUE;
2081 }
2082 
2083 
PubSeqCheckQueue(QUEUE * queue)2084 NLM_EXTERN Int4 PubSeqCheckQueue (
2085   QUEUE* queue
2086 )
2087 
2088 {
2089   return QUERY_CheckQueue (queue);
2090 }
2091 
2092 
GiRevHistAsynchronousQuery(BIG_ID uid,Int4 num,BIG_ID_PNTR uids,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2093 NLM_EXTERN Boolean GiRevHistAsynchronousQuery (
2094   BIG_ID uid,
2095   Int4 num,
2096   BIG_ID_PNTR uids,
2097   QUEUE* queue,
2098   QueryResultProc resultproc,
2099   VoidPtr userdata
2100 )
2101 
2102 {
2103   CONN  conn;
2104 
2105   conn = GiRevHistOpenConnection (uid, num, uids);
2106 
2107   if (conn == NULL) return FALSE;
2108 
2109   QUERY_SendQuery (conn);
2110 
2111   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2112 
2113   return TRUE;
2114 }
2115 
2116 
GiRevHistCheckQueue(QUEUE * queue)2117 NLM_EXTERN Int4 GiRevHistCheckQueue (
2118   QUEUE* queue
2119 )
2120 
2121 {
2122   return QUERY_CheckQueue (queue);
2123 }
2124 
2125 
GiAccVerAsynchronousQuery(BIG_ID uid,Int4 num,BIG_ID_PNTR uids,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2126 NLM_EXTERN Boolean GiAccVerAsynchronousQuery (
2127   BIG_ID uid,
2128   Int4 num,
2129   BIG_ID_PNTR uids,
2130   QUEUE* queue,
2131   QueryResultProc resultproc,
2132   VoidPtr userdata
2133 )
2134 
2135 {
2136   CONN  conn;
2137 
2138   conn = GiAccVerOpenConnection (uid, num, uids);
2139 
2140   if (conn == NULL) return FALSE;
2141 
2142   QUERY_SendQuery (conn);
2143 
2144   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2145 
2146   return TRUE;
2147 }
2148 
2149 
GiAccVerCheckQueue(QUEUE * queue)2150 NLM_EXTERN Int4 GiAccVerCheckQueue (
2151   QUEUE* queue
2152 )
2153 
2154 {
2155   return QUERY_CheckQueue (queue);
2156 }
2157 
2158 
AccnRevHistAsynchronousQuery(CharPtr accn,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2159 NLM_EXTERN Boolean AccnRevHistAsynchronousQuery (
2160   CharPtr accn,
2161   QUEUE* queue,
2162   QueryResultProc resultproc,
2163   VoidPtr userdata
2164 )
2165 
2166 {
2167   CONN  conn;
2168 
2169   conn = AccnRevHistOpenConnection (accn);
2170 
2171   if (conn == NULL) return FALSE;
2172 
2173   QUERY_SendQuery (conn);
2174 
2175   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2176 
2177   return TRUE;
2178 }
2179 
2180 
AccnRevHistCheckQueue(QUEUE * queue)2181 NLM_EXTERN Int4 AccnRevHistCheckQueue (
2182   QUEUE* queue
2183 )
2184 
2185 {
2186   return QUERY_CheckQueue (queue);
2187 }
2188 
2189 
GiSeqIdSetAsynchronousQuery(BIG_ID gi,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2190 NLM_EXTERN Boolean GiSeqIdSetAsynchronousQuery (
2191   BIG_ID gi,
2192   QUEUE* queue,
2193   QueryResultProc resultproc,
2194   VoidPtr userdata
2195 )
2196 
2197 {
2198   CONN  conn;
2199 
2200   conn = GiSeqIdSetOpenConnection (gi);
2201 
2202   if (conn == NULL) return FALSE;
2203 
2204   QUERY_SendQuery (conn);
2205 
2206   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2207 
2208   return TRUE;
2209 }
2210 
2211 
GiSeqIdSetCheckQueue(QUEUE * queue)2212 NLM_EXTERN Int4 GiSeqIdSetCheckQueue (
2213   QUEUE* queue
2214 )
2215 
2216 {
2217   return QUERY_CheckQueue (queue);
2218 }
2219 
2220 
AccnListAsynchronousQuery(CharPtr PNTR accns,QUEUE * queue,QueryResultProc resultproc,VoidPtr userdata)2221 NLM_EXTERN Boolean AccnListAsynchronousQuery (
2222   CharPtr PNTR accns,
2223   QUEUE* queue,
2224   QueryResultProc resultproc,
2225   VoidPtr userdata
2226 )
2227 
2228 {
2229   CONN  conn;
2230 
2231   conn = AccnListOpenConnection (accns);
2232 
2233   if (conn == NULL) return FALSE;
2234 
2235   QUERY_SendQuery (conn);
2236 
2237   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
2238 
2239   return TRUE;
2240 }
2241 
2242 
AccnListCheckQueue(QUEUE * queue)2243 NLM_EXTERN Int4 AccnListCheckQueue (
2244   QUEUE* queue
2245 )
2246 
2247 {
2248   return QUERY_CheckQueue (queue);
2249 }
2250 
2251 
2252 /* object manager registerable fetch functions */
2253 
2254 static CharPtr pubseqfetchproc = "PubSeqBioseqFetch";
2255 static CharPtr tracefetchproc = "TraceBioseqFetch";
2256 static CharPtr srafetchproc = "SRABioseqFetch";
2257 static CharPtr pubseqseqidtogi = "PubSeqSeqIdForGi";
2258 static CharPtr pubseqgitoseqid = "PubSeqGiForSeqId";
2259 
2260 static Boolean  fetch_fail_warn = FALSE;
2261 static Boolean  fetch_fail_warn_set = FALSE;
2262 
2263 static Boolean  fetch_succeed_log = FALSE;
2264 static Boolean  fetch_succeed_log_set = FALSE;
2265 
2266 static Int4 pubseqfetchflags = -1;
2267 
PubSeqBioseqFetchFunc(Pointer data)2268 static Int2 LIBCALLBACK PubSeqBioseqFetchFunc (Pointer data)
2269 
2270 {
2271   BioseqPtr         bsp;
2272   DbtagPtr          dbt;
2273   OMUserDataPtr     omdp = NULL;
2274   OMProcControlPtr  ompcp;
2275   ObjMgrProcPtr     ompp;
2276   Int2              retcode = 0;
2277   SeqEntryPtr       sep = NULL;
2278   SeqIdPtr          sip;
2279   BIG_ID            uid = 0;
2280   Char              id_buf[PATH_MAX];
2281 #ifdef OS_UNIX
2282   Char              id [64];
2283   BioseqPtr         firstbsp;
2284   SeqEntryPtr       firstsep;
2285   ObjMgrPtr         omp;
2286   CharPtr           str;
2287 #endif
2288 
2289   ompcp = (OMProcControlPtr) data;
2290   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2291   ompp = ompcp->proc;
2292   if (ompp == NULL) return OM_MSG_RET_ERROR;
2293   sip = (SeqIdPtr) ompcp->input_data;
2294   if (sip == NULL) return OM_MSG_RET_ERROR;
2295 
2296 #ifdef OS_UNIX
2297   if (! fetch_fail_warn_set) {
2298     str = (CharPtr) getenv ("PUBSEQ_FETCH_FAIL_WARN");
2299     if (StringDoesHaveText (str)) {
2300       if (StringICmp (str, "TRUE") == 0) {
2301         fetch_fail_warn = TRUE;
2302       }
2303     }
2304     fetch_fail_warn_set = TRUE;
2305   }
2306 
2307   if (! fetch_succeed_log_set) {
2308     str = (CharPtr) getenv ("PUBSEQ_FETCH_SUCCEED_LOG");
2309     if (StringDoesHaveText (str)) {
2310       if (StringICmp (str, "TRUE") == 0) {
2311         fetch_succeed_log = TRUE;
2312       }
2313     }
2314     fetch_succeed_log_set = TRUE;
2315   }
2316 #endif
2317 
2318   id_buf[0] = 0;
2319 
2320   omdp = ObjMgrGetUserData (ompcp->input_entityID, ompp->procid, OMPROC_FETCH, 0);
2321   if (omdp != NULL) {
2322     uid = omdp->userdata.intvalue;
2323 #ifdef OS_UNIX
2324     if (fetch_succeed_log) {
2325       ErrPostEx (SEV_ERROR, 0, 0, "PSFetch reloading gi %lld", uid);
2326     }
2327 #endif
2328     if (uid == 0) return OM_MSG_RET_ERROR;
2329   } else if (sip->choice == SEQID_GI) {
2330     uid = sip->data.intvalue;
2331   } else if (sip->choice != SEQID_LOCAL) {
2332     uid = GetGIForSeqId (sip);
2333   }
2334 
2335   if (uid == 0 && sip->choice != SEQID_LOCAL) {
2336     if (sip->choice == SEQID_GENERAL) {
2337       dbt = (DbtagPtr) sip->data.ptrvalue;
2338       if (dbt != NULL && ((StringICmp (dbt->db, "ti") == 0 || StringICmp (dbt->db, "SRA") == 0))) {
2339         SeqIdWrite (sip, id_buf, PRINTID_FASTA_SHORT, sizeof (id_buf) - 1);
2340       }
2341     } else {
2342       SeqIdWrite (sip, id_buf, PRINTID_FASTA_SHORT, sizeof (id_buf) - 1);
2343     }
2344   }
2345 
2346   if (uid != 0 || StringDoesHaveText (id_buf)) {
2347     sep = PubSeqSynchronousQueryEx (uid, retcode, pubseqfetchflags, id_buf);
2348   }
2349 
2350   if (sep == NULL) {
2351 #ifdef OS_UNIX
2352     if (fetch_fail_warn) {
2353       ErrPostEx (SEV_ERROR, 0, 0, "PSSyncQuery failed for gi %lld", (long long) uid);
2354     }
2355 #endif
2356     return OM_MSG_RET_OK;
2357   }
2358   bsp = BioseqFindInSeqEntry (sip, sep);
2359 
2360 #ifdef OS_UNIX
2361   if (bsp != NULL) {
2362     if (fetch_succeed_log) {
2363       ErrPostEx (SEV_ERROR, 0, 0, "PSFetch succeeded for gi %lld", (long long) uid);
2364     }
2365   }
2366 
2367   if (bsp == NULL) {
2368     if (fetch_fail_warn) {
2369       firstsep = FindNthBioseq (sep, 1);
2370       if (firstsep != NULL && IS_Bioseq (firstsep)) {
2371         firstbsp = (BioseqPtr) firstsep->data.ptrvalue;
2372         if (firstbsp != NULL && firstbsp->id != NULL) {
2373           SeqIdWrite (firstbsp->id, id, PRINTID_FASTA_LONG, sizeof (id) - 1);
2374           ErrPostEx (SEV_ERROR, 0, 0, "PubSeqBioseqFetchFunc requested gi %lld, got %s", (long long) uid, id);
2375           omp = ObjMgrGet ();
2376           if (omp != NULL) {
2377             ErrPostEx (SEV_ERROR, 0, 0, "ObjMgr highEid %d totobj %d currobj %d maxtemp %d tempcnt %d hold %d",
2378                        (int) omp->HighestEntityID, (int) omp->totobj, (int) omp->currobj,
2379                        (int) omp->maxtemp, (int) omp->tempcnt, (int) omp->hold);
2380           }
2381         }
2382       }
2383     }
2384   }
2385 #endif
2386 
2387   ompcp->output_data = (Pointer) bsp;
2388   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
2389 
2390   omdp = ObjMgrAddUserData (ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
2391   if (omdp != NULL) {
2392     omdp->userdata.intvalue = uid;
2393   }
2394 
2395   return OM_MSG_RET_DONE;
2396 }
2397 
2398 
TraceBioseqFetchFunc(Pointer data)2399 static Int2 LIBCALLBACK TraceBioseqFetchFunc (Pointer data)
2400 
2401 {
2402   BioseqPtr         bsp;
2403   DbtagPtr          dbt;
2404   ObjectIdPtr       oip;
2405   OMUserDataPtr     omdp = NULL;
2406   OMProcControlPtr  ompcp;
2407   ObjMgrProcPtr     ompp;
2408   Int2              retcode = 0;
2409   SeqEntryPtr       sep = NULL;
2410   SeqIdPtr          sip;
2411   Int4              uid = 0;
2412 
2413   ompcp = (OMProcControlPtr) data;
2414   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2415   ompp = ompcp->proc;
2416   if (ompp == NULL) return OM_MSG_RET_ERROR;
2417   sip = (SeqIdPtr) ompcp->input_data;
2418   if (sip == NULL) return OM_MSG_RET_ERROR;
2419 
2420   omdp = ObjMgrGetUserData (ompcp->input_entityID, ompp->procid, OMPROC_FETCH, 0);
2421   if (omdp != NULL) {
2422     uid = omdp->userdata.intvalue;
2423     if (uid == 0) return OM_MSG_RET_ERROR;
2424   } else if (sip->choice == SEQID_GENERAL) {
2425     dbt = (DbtagPtr) sip->data.ptrvalue;
2426     if (dbt == NULL) return OM_MSG_RET_OK;
2427     if (StringICmp (dbt->db, "ti") != 0) return OM_MSG_RET_OK;
2428     oip = dbt->tag;
2429     if (oip == NULL || oip->id == 0) return OM_MSG_RET_OK;
2430     uid = oip->id;
2431   }
2432 
2433   if (uid == 0) return OM_MSG_RET_OK;
2434 
2435   sep = PubSeqSynchronousQueryTI (uid, retcode, pubseqfetchflags);
2436 
2437   if (sep == NULL) {
2438     return OM_MSG_RET_OK;
2439   }
2440   bsp = BioseqFindInSeqEntry (sip, sep);
2441 
2442   ompcp->output_data = (Pointer) bsp;
2443   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
2444 
2445   omdp = ObjMgrAddUserData (ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
2446   if (omdp != NULL) {
2447     omdp->userdata.intvalue = uid;
2448   }
2449 
2450   return OM_MSG_RET_DONE;
2451 }
2452 
2453 
FreeSraID(Pointer data)2454 static Pointer LIBCALLBACK FreeSraID (Pointer data)
2455 
2456 {
2457   MemFree (data);
2458   return NULL;
2459 }
2460 
2461 
SRABioseqFetchFunc(Pointer data)2462 static Int2 LIBCALLBACK SRABioseqFetchFunc (Pointer data)
2463 
2464 {
2465   BioseqPtr         bsp;
2466   DbtagPtr          dbt;
2467   ObjectIdPtr       oip;
2468   OMUserDataPtr     omdp = NULL;
2469   OMProcControlPtr  ompcp;
2470   ObjMgrProcPtr     ompp;
2471   SeqEntryPtr       sep = NULL;
2472   SeqIdPtr          sip;
2473   CharPtr           sraid = NULL;
2474 
2475   ompcp = (OMProcControlPtr) data;
2476   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2477   ompp = ompcp->proc;
2478   if (ompp == NULL) return OM_MSG_RET_ERROR;
2479   sip = (SeqIdPtr) ompcp->input_data;
2480   if (sip == NULL) return OM_MSG_RET_ERROR;
2481 
2482   omdp = ObjMgrGetUserData (ompcp->input_entityID, ompp->procid, OMPROC_FETCH, 0);
2483   if (omdp != NULL) {
2484     sraid = omdp->userdata.ptrvalue;
2485     if (sraid == NULL) return OM_MSG_RET_ERROR;
2486   } else if (sip->choice == SEQID_GENERAL) {
2487     dbt = (DbtagPtr) sip->data.ptrvalue;
2488     if (dbt == NULL) return OM_MSG_RET_OK;
2489     if (StringICmp (dbt->db, "SRA") != 0) return OM_MSG_RET_OK;
2490     oip = dbt->tag;
2491     if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
2492     sraid = oip->str;
2493   }
2494 
2495   if (sraid == NULL) return OM_MSG_RET_OK;
2496 
2497   sep = PubSeqSynchronousQuerySRA (sraid);
2498 
2499   if (sep == NULL) {
2500     return OM_MSG_RET_OK;
2501   }
2502   bsp = BioseqFindInSeqEntry (sip, sep);
2503 
2504   ompcp->output_data = (Pointer) bsp;
2505   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
2506 
2507   omdp = ObjMgrAddUserData (ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
2508   if (omdp != NULL) {
2509     omdp->userdata.ptrvalue = StringSave (sraid);
2510     omdp->freefunc = FreeSraID;
2511   }
2512 
2513   return OM_MSG_RET_DONE;
2514 }
2515 
2516 
PubSeqSeqIdForGiFunc(Pointer data)2517 static Int2 LIBCALLBACK PubSeqSeqIdForGiFunc (Pointer data)
2518 
2519 {
2520   Char              ch;
2521   OMProcControlPtr  ompcp;
2522   ObjMgrProcPtr     ompp;
2523   CharPtr           ptr;
2524   SeqIdPtr          sid = NULL;
2525   SeqIdPtr          sip;
2526   CharPtr           str;
2527   BIG_ID            uid;
2528 
2529   ompcp = (OMProcControlPtr) data;
2530   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2531   ompp = ompcp->proc;
2532   if (ompp == NULL) return OM_MSG_RET_ERROR;
2533   sip = (SeqIdPtr) ompcp->input_data;
2534   if (sip == NULL) return OM_MSG_RET_ERROR;
2535 
2536   if (sip->choice != SEQID_GI) return OM_MSG_RET_ERROR;
2537   uid = (BIG_ID) sip->data.intvalue;
2538   if (uid < 1) return OM_MSG_RET_ERROR;
2539 
2540   str = GiRevHistSynchronousQuery (uid, 0, NULL);
2541   if (str == NULL) return OM_MSG_RET_ERROR;
2542 
2543   ptr = str;
2544   ch = *ptr;
2545   while (ch != '\0' && ch != '\n' && ch != '\r') {
2546     ptr++;
2547     ch = *ptr;
2548   }
2549   *ptr = '\0';
2550 
2551   if (StringNCmp (str, "ERROR", 5) != 0 && StringNCmp (str, "<!DOCTYPE", 9) != 0) {
2552     sid = SeqIdParse (str);
2553   }
2554   MemFree (str);
2555 
2556   if (sid == NULL) return OM_MSG_RET_ERROR;
2557 
2558   ompcp->output_data = (Pointer) sid;
2559   return OM_MSG_RET_DONE;
2560 }
2561 
2562 
PubSeqGiForSeqIdFunc(Pointer data)2563 static Int2 LIBCALLBACK PubSeqGiForSeqIdFunc (Pointer data)
2564 
2565 {
2566   Char              buf [41];
2567   BIG_ID            gi;
2568   OMProcControlPtr  ompcp;
2569   ObjMgrProcPtr     ompp;
2570   SeqIdPtr          sid;
2571   SeqIdPtr          sip;
2572 
2573   ompcp = (OMProcControlPtr) data;
2574   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2575   ompp = ompcp->proc;
2576   if (ompp == NULL) return OM_MSG_RET_ERROR;
2577   sip = (SeqIdPtr) ompcp->input_data;
2578   if (sip == NULL) return OM_MSG_RET_ERROR;
2579 
2580   if (sip->choice == SEQID_GI) return OM_MSG_RET_ERROR;
2581   if (sip->choice == SEQID_LOCAL) return OM_MSG_RET_OK;
2582  if (sip->choice == SEQID_GENERAL) return OM_MSG_RET_OK;
2583   SeqIdWrite (sip, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf));
2584   if (StringHasNoText (buf)) return OM_MSG_RET_ERROR;
2585 
2586   gi = AccnRevHistSynchronousQuery (buf);
2587   if (gi < 1) return OM_MSG_RET_ERROR;
2588 
2589   sid = ValNodeNew (NULL);
2590   if (sid == NULL) return OM_MSG_RET_ERROR;
2591   sid->choice = SEQID_GI;
2592   sid->data.intvalue = gi;
2593   sid->next = NULL;
2594 
2595   ompcp->output_data = (Pointer) sid;
2596   return OM_MSG_RET_DONE;
2597 }
2598 
2599 
PubSeqFetchEnable(void)2600 NLM_EXTERN Boolean PubSeqFetchEnable (void)
2601 
2602 {
2603   ObjMgrProcLoad (OMPROC_FETCH, srafetchproc, srafetchproc,
2604                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2605                   SRABioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2606 
2607   ObjMgrProcLoad (OMPROC_FETCH, tracefetchproc, tracefetchproc,
2608                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2609                   TraceBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2610 
2611   ObjMgrProcLoad (OMPROC_FETCH, pubseqfetchproc, pubseqfetchproc,
2612                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2613                   PubSeqBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2614 
2615   ObjMgrProcLoad (OMPROC_FETCH, pubseqseqidtogi, pubseqseqidtogi,
2616                   OBJ_SEQID, SEQID_GI, OBJ_SEQID, 0, NULL,
2617                   PubSeqSeqIdForGiFunc, PROC_PRIORITY_DEFAULT);
2618 
2619   ObjMgrProcLoad (OMPROC_FETCH, pubseqgitoseqid, pubseqgitoseqid,
2620                   OBJ_SEQID, 0, OBJ_SEQID, SEQID_GI, NULL,
2621                   PubSeqGiForSeqIdFunc, PROC_PRIORITY_DEFAULT);
2622 
2623   SeqMgrSetPreCache (GiRevHistLookupFarSeqIDs);
2624 
2625   SeqMgrSetSeqIdSetFunc (GiRevHistLookupSeqIdSet);
2626 
2627   return TRUE;
2628 }
2629 
2630 
PubSeqFetchEnableEx(Boolean fetch,Boolean seqidtogi,Boolean gitoseqid,Boolean precache,Boolean seqidset,Int4 flags)2631 NLM_EXTERN Boolean PubSeqFetchEnableEx (
2632   Boolean fetch,
2633   Boolean seqidtogi,
2634   Boolean gitoseqid,
2635   Boolean precache,
2636   Boolean seqidset,
2637   Int4 flags
2638 )
2639 
2640 {
2641   if (fetch) {
2642     ObjMgrProcLoad (OMPROC_FETCH, srafetchproc, srafetchproc,
2643                     OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2644                     SRABioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2645 
2646     ObjMgrProcLoad (OMPROC_FETCH, tracefetchproc, tracefetchproc,
2647                     OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2648                     TraceBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2649 
2650     ObjMgrProcLoad (OMPROC_FETCH, pubseqfetchproc, pubseqfetchproc,
2651                     OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2652                     PubSeqBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2653   }
2654 
2655   if (seqidtogi) {
2656     ObjMgrProcLoad (OMPROC_FETCH, pubseqseqidtogi, pubseqseqidtogi,
2657                     OBJ_SEQID, SEQID_GI, OBJ_SEQID, 0, NULL,
2658                     PubSeqSeqIdForGiFunc, PROC_PRIORITY_DEFAULT);
2659   }
2660 
2661   if (gitoseqid) {
2662     ObjMgrProcLoad (OMPROC_FETCH, pubseqgitoseqid, pubseqgitoseqid,
2663                     OBJ_SEQID, 0, OBJ_SEQID, SEQID_GI, NULL,
2664                     PubSeqGiForSeqIdFunc, PROC_PRIORITY_DEFAULT);
2665   }
2666 
2667   if (precache) {
2668     SeqMgrSetPreCache (GiRevHistLookupFarSeqIDs);
2669   }
2670 
2671   if (seqidset) {
2672     SeqMgrSetSeqIdSetFunc (GiRevHistLookupSeqIdSet);
2673   }
2674 
2675   pubseqfetchflags = flags;
2676 
2677   return TRUE;
2678 }
2679 
2680 
PubSeqFetchDisable(void)2681 NLM_EXTERN void PubSeqFetchDisable (void)
2682 
2683 {
2684   ObjMgrPtr      omp;
2685   ObjMgrProcPtr  ompp;
2686 
2687   omp = ObjMgrGet ();
2688   ompp = ObjMgrProcFind (omp, 0, srafetchproc, OMPROC_FETCH);
2689   if (ompp != NULL) {
2690     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2691   }
2692   ompp = ObjMgrProcFind (omp, 0, tracefetchproc, OMPROC_FETCH);
2693   if (ompp != NULL) {
2694     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2695   }
2696   ompp = ObjMgrProcFind (omp, 0, pubseqfetchproc, OMPROC_FETCH);
2697   if (ompp != NULL) {
2698     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2699   }
2700   ompp = ObjMgrProcFind (omp, 0, pubseqseqidtogi, OMPROC_FETCH);
2701   if (ompp != NULL) {
2702     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2703   }
2704   ompp = ObjMgrProcFind (omp, 0, pubseqgitoseqid, OMPROC_FETCH);
2705   if (ompp != NULL) {
2706     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2707   }
2708 
2709   SeqMgrSetPreCache (NULL);
2710 
2711   SeqMgrSetSeqIdSetFunc (NULL);
2712 }
2713 
2714 
2715 /* multiple Accession preload into cache or report function */
2716 
CacheAccnList(CharPtr str,CacheAccnListProc userfunc)2717 NLM_EXTERN Int4 CacheAccnList (
2718   CharPtr str,
2719   CacheAccnListProc userfunc
2720 )
2721 
2722 {
2723   SeqIdPtr  accn;
2724   Char      buf [41];
2725   Char      ch;
2726   Int4      count = 0;
2727   BIG_ID    gi;
2728   Int4      i;
2729   SeqIdPtr  ids;
2730   CharPtr   ptr;
2731   SeqIdPtr  sip;
2732   CharPtr   tmp;
2733 
2734   if (str == NULL) return 0;
2735 
2736   if (StringNCmp (str, "<!DOCTYPE", 9) == 0) return 0;
2737 
2738   /* parse output */
2739 
2740   i = 0;
2741   ptr = str;
2742   ch = *ptr;
2743   while (ch != '\0') {
2744     tmp = ptr;
2745     while (ch != '\0' && ch != '\n' && ch != '\r') {
2746       ptr++;
2747       ch = *ptr;
2748     }
2749     *ptr = '\0';
2750     while (ch == '\n' || ch == '\r') {
2751       ptr++;
2752       ch = *ptr;
2753     }
2754     if (StringNCmp (tmp, "ERROR", 5) != 0 &&
2755         StringNCmp (tmp, "<!DOCTYPE", 9) != 0 &&
2756         StringNCmp (tmp, "Sorry", 5) != 0 &&
2757         StringChr (tmp, '|') != NULL) {
2758       ids = SeqIdParse (tmp);
2759       if (ids != NULL) {
2760         gi = 0;
2761         accn = NULL;
2762         for (sip = ids; sip != NULL; sip = sip->next) {
2763           switch (sip->choice) {
2764             case SEQID_GI :
2765               gi = (BIG_ID) sip->data.intvalue;
2766               break;
2767             case SEQID_GENBANK :
2768             case SEQID_EMBL :
2769             case SEQID_PIR :
2770             case SEQID_SWISSPROT :
2771             case SEQID_PATENT :
2772             case SEQID_OTHER :
2773             case SEQID_DDBJ :
2774             case SEQID_PRF :
2775             case SEQID_TPG :
2776             case SEQID_TPE :
2777             case SEQID_TPD :
2778             case SEQID_GPIPE :
2779               accn = sip;
2780               break;
2781             default :
2782               break;
2783           }
2784         }
2785         if (gi > 0 && accn != NULL) {
2786 
2787           if (userfunc != NULL) {
2788 
2789             SeqIdWrite (accn, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 1);
2790             if (! StringHasNoText (buf)) {
2791               userfunc (gi, buf);
2792               count++;
2793             }
2794 
2795           } else {
2796 
2797             RecordInSeqIdGiCache (gi, accn);
2798             count++;
2799           }
2800         }
2801         SeqIdSetFree (ids);
2802       }
2803     }
2804     i++;
2805   }
2806 
2807   return count;
2808 }
2809 
2810 
2811 /* multiple SeqId preload into cache function */
2812 
SortByInt4(VoidPtr vp1,VoidPtr vp2)2813 static int LIBCALLBACK SortByInt4 (VoidPtr vp1, VoidPtr vp2)
2814 
2815 {
2816   Int4Ptr ip1 = (Int4Ptr) vp1;
2817   Int4Ptr ip2 = (Int4Ptr) vp2;
2818 
2819   if (ip1 == NULL || ip2 == NULL) return 0;
2820   if (*ip1 > *ip2) return 1;
2821   if (*ip1 < *ip2) return -1;
2822   return 0;
2823 }
2824 
SortByBIG_ID(VoidPtr vp1,VoidPtr vp2)2825 static int LIBCALLBACK SortByBIG_ID (VoidPtr vp1, VoidPtr vp2)
2826 
2827 {
2828   BIG_ID_PNTR ip1 = (BIG_ID_PNTR) vp1;
2829   BIG_ID_PNTR ip2 = (BIG_ID_PNTR) vp2;
2830 
2831   if (ip1 == NULL || ip2 == NULL) return 0;
2832   if (*ip1 > *ip2) return 1;
2833   if (*ip1 < *ip2) return -1;
2834   return 0;
2835 }
2836 
IntPreLoadSeqIdGiCache(Int4 num,BIG_ID_PNTR ids)2837 static Int4 IntPreLoadSeqIdGiCache (
2838   Int4 num,
2839   BIG_ID_PNTR ids
2840 )
2841 
2842 {
2843   Char      ch;
2844   Int4      count = 0;
2845   BIG_ID    gi;
2846   Int4      i;
2847   CharPtr   ptr;
2848   SeqIdPtr  sip;
2849   CharPtr   str;
2850   CharPtr   tmp;
2851 
2852   if (num < 1 || num > 500 || ids == NULL) return 0;
2853 
2854   /* perform multiple gi to SeqId query */
2855 
2856   /* str = GiRevHistSynchronousQuery (0, num, ids); */
2857   str = GiAccVerSynchronousQuery (0, num, ids);
2858   if (str == NULL) return 0;
2859 
2860   if (StringNCmp (str, "<!DOCTYPE", 9) == 0) return 0;
2861 
2862   /* parse output */
2863 
2864   i = 0;
2865   ptr = str;
2866   ch = *ptr;
2867   while (ch != '\0') {
2868     tmp = ptr;
2869     while (ch != '\0' && ch != '\n' && ch != '\r') {
2870       ptr++;
2871       ch = *ptr;
2872     }
2873     *ptr = '\0';
2874     while (ch == '\n' || ch == '\r') {
2875       ptr++;
2876       ch = *ptr;
2877     }
2878     if (StringNCmp (tmp, "ERROR", 5) != 0 && StringNCmp (tmp, "<!DOCTYPE", 9) != 0) {
2879       gi = ids [i];
2880 
2881       sip = NULL;
2882       if (StringChr (tmp, '|') != NULL) {
2883         sip = SeqIdParse (tmp);
2884       } else {
2885         sip = SeqIdFromAccessionDotVersion (tmp);
2886       }
2887       if (sip != NULL) {
2888         RecordInSeqIdGiCache (gi, sip);
2889         SeqIdSetFree (sip);
2890         count++;
2891       }
2892     }
2893     i++;
2894   }
2895 
2896   MemFree (str);
2897 
2898   return count;
2899 }
2900 
2901 
FilterKnownGis(Int4 num,BIG_ID_PNTR uniq,Boolean filter)2902 static Int4 FilterKnownGis (
2903   Int4 num,
2904   BIG_ID_PNTR uniq,
2905   Boolean filter
2906 )
2907 
2908 {
2909   BioseqPtr  bsp;
2910   BIG_ID     gi;
2911   Int4       i;
2912   BIG_ID     ids [501];
2913   Int4       j;
2914   ValNode    vn;
2915 
2916   if (num < 1 || num > 500 || uniq == NULL) return 0;
2917 
2918   MemSet ((Pointer) &vn, 0, sizeof (ValNode));
2919   vn.choice = SEQID_GI;
2920 
2921   /* eliminate uids we already know, load ids list with remainder */
2922 
2923   for (i = 0, j = 0; i < num; i++) {
2924     gi = uniq [i];
2925     if (gi < 1) continue;
2926 
2927     if (filter) {
2928       vn.data.intvalue = gi;
2929       bsp = BioseqFindCore (&vn);
2930       if (bsp != NULL) continue; /* already loaded */
2931 
2932       if (FetchFromSeqIdGiCache (gi, NULL)) continue; /* already cached */
2933     }
2934 
2935     ids [j] = gi;
2936     j++;
2937   }
2938 
2939   if (j < 1) return 0;
2940 
2941   return IntPreLoadSeqIdGiCache (j, ids);
2942 }
2943 
2944 
UniqPreLoadList(Int4 num,BIG_ID_PNTR srted,Boolean filter)2945 static Int4 UniqPreLoadList (
2946   Int4 num,
2947   BIG_ID_PNTR srted,
2948   Boolean filter
2949 )
2950 
2951 {
2952   BIG_ID gi;
2953   Int4  i;
2954   Int4  j;
2955   Int4  last;
2956   BIG_ID uniq [501];
2957 
2958   if (num < 1 || num > 500 || srted == NULL) return 0;
2959 
2960   /* unique uid list */
2961 
2962   last = 0;
2963   for (i = 0, j = 0; i < num; i++) {
2964     gi = srted [i];
2965     if (gi != last) {
2966       uniq [j] = gi;
2967       j++;
2968     }
2969     last = gi;
2970   }
2971   num = j;
2972 
2973   return FilterKnownGis (num, uniq, filter);
2974 }
2975 
2976 
SortPreLoadList(Int4 num,BIG_ID_PNTR raw,Boolean filter)2977 static Int4 SortPreLoadList (
2978   Int4 num,
2979   BIG_ID_PNTR raw,
2980   Boolean filter
2981 )
2982 
2983 {
2984   Int4  i;
2985   BIG_ID  uids [501];
2986 
2987   if (num < 1 || num > 500 || raw == NULL) return 0;
2988 
2989   /* copy raw uid list */
2990 
2991   for (i = 0; i < num; i++) {
2992     uids [i] = raw [i];
2993   }
2994 
2995   /* sort by gi value */
2996 
2997   HeapSort ((Pointer) uids, (size_t) num, sizeof (BIG_ID), SortByBIG_ID);
2998 
2999   return UniqPreLoadList (num, uids, filter);
3000 }
3001 
3002 
GiRevHistPreLoadSeqIdGiCacheEx(Int4 num,BIG_ID_PNTR uids,Boolean filter)3003 NLM_EXTERN Int4 GiRevHistPreLoadSeqIdGiCacheEx (
3004   Int4 num,
3005   BIG_ID_PNTR uids,
3006   Boolean filter
3007 )
3008 
3009 {
3010   Int4  count;
3011   Int4  offset;
3012   Int4  rsult = 0;
3013 
3014   /* split into queries of 500 or fewer uids at a time */
3015 
3016   if (num < 1 || uids == NULL) return 0;
3017   count = (Int4) MIN (num, 500L);
3018   offset = 0;
3019   while (count > 0 && num > 0) {
3020     rsult += SortPreLoadList (count, uids + offset, filter);
3021     offset += count;
3022     num -= count;
3023     count = (Int4) MIN (num, 500L);
3024   }
3025   return rsult;
3026 }
3027 
3028 
GiRevHistPreLoadSeqIdGiCache(Int4 num,BIG_ID_PNTR uids)3029 NLM_EXTERN Int4 GiRevHistPreLoadSeqIdGiCache (
3030   Int4 num,
3031   BIG_ID_PNTR uids
3032 )
3033 
3034 {
3035   return GiRevHistPreLoadSeqIdGiCacheEx (num, uids, TRUE);
3036 }
3037 
3038 
SortPreLoadAccns(Int4 num,CharPtr PNTR raw)3039 static Int4 SortPreLoadAccns (
3040   Int4 num,
3041   CharPtr PNTR raw
3042 )
3043 
3044 {
3045   CharPtr  accns [501];
3046   Int4     i, rsult = 0;
3047   CharPtr  str;
3048 
3049   if (num < 1 || num > 500 || raw == NULL) return 0;
3050 
3051   /* copy raw uid list */
3052 
3053   for (i = 0; i < num; i++) {
3054     accns [i] = raw [i];
3055   }
3056   accns [i] = NULL;
3057 
3058   str = AccnListSynchronousQuery (accns);
3059   if (str == NULL) return 0;
3060 
3061   rsult = CacheAccnList (str, NULL);
3062 
3063   MemFree (str);
3064   return rsult;
3065 }
3066 
3067 
AccnListPreLoadSeqIdGiCache(CharPtr PNTR accns)3068 NLM_EXTERN Int4 AccnListPreLoadSeqIdGiCache (
3069   CharPtr PNTR accns
3070 )
3071 
3072 {
3073   Int4  count, num, offset, rsult = 0;
3074 
3075   if (accns == NULL) return 0;
3076 
3077   for (num = 0; accns [num] != NULL; num++) continue;
3078   if (num < 1) return 0;
3079 
3080   count = (Int4) MIN (num, 500L);
3081   offset = 0;
3082 
3083   while (count > 0 && num > 0) {
3084     rsult += SortPreLoadAccns (count, accns + offset);
3085     offset += count;
3086     num -= count;
3087     count = (Int4) MIN (num, 500L);
3088   }
3089 
3090   return rsult;
3091 }
3092 
3093 
3094 typedef struct fariddata {
3095   ValNodePtr  gis;
3096   ValNodePtr  accns;
3097   ValNodePtr  strs;
3098 } FarIdData, PNTR FarIDPtr;
3099 
3100 
ReplaceSpacesWithPluses(CharPtr str)3101 static void ReplaceSpacesWithPluses (CharPtr str)
3102 {
3103   CharPtr cp;
3104 
3105   if (str == NULL) return;
3106 
3107   for (cp = str; *cp; cp++)
3108   {
3109     if (*cp == ' ')
3110     {
3111       *cp = '+';
3112     }
3113   }
3114 }
3115 
3116 
LookupSegments(SeqLocPtr slp,SeqIdPtr sip,Pointer userdata)3117 static void LookupSegments (SeqLocPtr slp, SeqIdPtr sip, Pointer userdata)
3118 
3119 {
3120   FarIDPtr    fip;
3121   SeqLocPtr   loc;
3122   ValNodePtr  vnp;
3123 
3124   if (slp == NULL && sip == NULL) return;
3125   if (userdata == NULL) return;
3126   fip = (FarIDPtr) userdata;
3127 
3128   if (sip == NULL) {
3129     sip = SeqLocId (slp);
3130     if (sip == NULL) {
3131       loc = SeqLocFindNext (slp, NULL);
3132       if (loc != NULL) {
3133         sip = SeqLocId (loc);
3134       }
3135     }
3136   }
3137   if (sip == NULL) return;
3138 
3139   switch (sip->choice) {
3140     case SEQID_GI :
3141       vnp = ValNodeAddBigInt (NULL, 0, sip->data.intvalue);
3142       if (fip->gis == NULL) {
3143         fip->gis = vnp;
3144       } else {
3145         vnp->next = fip->gis;
3146         fip->gis = vnp;
3147       }
3148       break;
3149     case SEQID_GENBANK :
3150     case SEQID_EMBL :
3151     case SEQID_DDBJ :
3152     case SEQID_TPG :
3153     case SEQID_TPE :
3154     case SEQID_TPD :
3155     case SEQID_OTHER :
3156     case SEQID_GPIPE :
3157       vnp = ValNodeAddPointer (NULL, 0, sip);
3158       if (fip->accns == NULL) {
3159         fip->accns = vnp;
3160       } else {
3161         vnp->next = fip->accns;
3162         fip->accns = vnp;
3163       }
3164       break;
3165     default :
3166       break;
3167   }
3168 }
3169 
3170 
LookupBioseqs(BioseqPtr bsp,Pointer userdata)3171 static void LookupBioseqs (BioseqPtr bsp, Pointer userdata)
3172 
3173 {
3174   DeltaSeqPtr  dsp;
3175   SeqLocPtr    slp = NULL;
3176   ValNode      vn;
3177 
3178   if (bsp == NULL) return;
3179 
3180   if (bsp->repr == Seq_repr_seg) {
3181     vn.choice = SEQLOC_MIX;
3182     vn.extended = 0;
3183     vn.data.ptrvalue = bsp->seq_ext;
3184     vn.next = NULL;
3185     while ((slp = SeqLocFindNext (&vn, slp)) != NULL) {
3186       if (slp != NULL && slp->choice != SEQLOC_NULL) {
3187         LookupSegments (slp, NULL, userdata);
3188       }
3189     }
3190   } else if (bsp->repr == Seq_repr_delta) {
3191     for (dsp = (DeltaSeqPtr) (bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
3192       if (dsp->choice == 1) {
3193         slp = (SeqLocPtr) dsp->data.ptrvalue;
3194         if (slp != NULL && slp->choice != SEQLOC_NULL) {
3195           LookupSegments (slp, NULL, userdata);
3196         }
3197       }
3198     }
3199   }
3200 }
3201 
3202 
LookupLocations(SeqFeatPtr sfp,Pointer userdata)3203 static void LookupLocations (SeqFeatPtr sfp, Pointer userdata)
3204 
3205 {
3206   SeqLocPtr  slp = NULL;
3207 
3208   if (sfp == NULL) return;
3209 
3210   while ((slp = SeqLocFindNext (sfp->location, slp)) != NULL) {
3211     if (slp != NULL && slp->choice != SEQLOC_NULL) {
3212       LookupSegments (slp, NULL, userdata);
3213     }
3214   }
3215 }
3216 
3217 
LookupProducts(SeqFeatPtr sfp,Pointer userdata)3218 static void LookupProducts (SeqFeatPtr sfp, Pointer userdata)
3219 
3220 {
3221   SeqLocPtr  slp = NULL;
3222 
3223   if (sfp == NULL) return;
3224 
3225   while ((slp = SeqLocFindNext (sfp->product, slp)) != NULL) {
3226     if (slp != NULL && slp->choice != SEQLOC_NULL) {
3227       LookupSegments (slp, NULL, userdata);
3228     }
3229   }
3230 }
3231 
3232 
LookupAlignments(SeqAlignPtr sap,Pointer userdata)3233 static void LookupAlignments (SeqAlignPtr sap, Pointer userdata)
3234 
3235 {
3236   DenseDiagPtr  ddp;
3237   DenseSegPtr   dsp;
3238   SeqIdPtr      sip;
3239   SeqLocPtr     slp = NULL;
3240   StdSegPtr     ssp;
3241 
3242   if (sap == NULL) return;
3243 
3244   LookupSegments (sap->bounds, NULL, userdata);
3245   if (sap->segs == NULL) return;
3246 
3247   switch (sap->segtype) {
3248     case SAS_DENDIAG :
3249       ddp = (DenseDiagPtr) sap->segs;
3250       if (ddp != NULL) {
3251         for (sip = ddp->id; sip != NULL; sip = sip->next) {
3252           LookupSegments (NULL, sip, userdata);
3253         }
3254       }
3255       break;
3256     case SAS_DENSEG :
3257       dsp = (DenseSegPtr) sap->segs;
3258       if (dsp != NULL) {
3259         for (sip = dsp->ids; sip != NULL; sip = sip->next) {
3260           LookupSegments (NULL, sip, userdata);
3261         }
3262       }
3263       break;
3264     case SAS_STD :
3265       ssp = (StdSegPtr) sap->segs;
3266       for (slp = ssp->loc; slp != NULL; slp = slp->next) {
3267         LookupSegments (slp, NULL, userdata);
3268       }
3269       break;
3270     case SAS_DISC :
3271       /* recursive */
3272       for (sap = (SeqAlignPtr) sap->segs; sap != NULL; sap = sap->next) {
3273         LookupAlignments (sap, userdata);
3274       }
3275       break;
3276     default :
3277       break;
3278   }
3279 }
3280 
3281 
LookupHistory(BioseqPtr bsp,Pointer userdata)3282 static void LookupHistory (BioseqPtr bsp, Pointer userdata)
3283 
3284 {
3285   SeqHistPtr  hist;
3286   SeqIdPtr    sip;
3287   SeqAlignPtr salp;
3288 
3289   if (bsp == NULL) return;
3290   hist = bsp->hist;
3291   if (hist == NULL) return;
3292   if (hist->assembly != NULL) {
3293     for (salp = hist->assembly; salp != NULL; salp = salp->next) {
3294       LookupAlignments (salp, userdata);
3295     }
3296   }
3297   for (sip = hist->replace_ids; sip != NULL; sip = sip->next) {
3298     LookupSegments (NULL, sip, userdata);
3299   }
3300   for (sip = hist->replaced_by_ids; sip != NULL; sip = sip->next) {
3301     LookupSegments (NULL, sip, userdata);
3302   }
3303 }
3304 
3305 
LookupOthers(SeqDescrPtr sdp,Pointer userdata)3306 static void LookupOthers (SeqDescrPtr sdp, Pointer userdata)
3307 
3308 {
3309   SeqIdPtr    sip;
3310   SPBlockPtr  spb;
3311 
3312   if (sdp == NULL || sdp->choice != Seq_descr_sp) return;
3313   spb = (SPBlockPtr) sdp->data.ptrvalue;
3314   if (spb == NULL) return;
3315 
3316   for (sip = spb->seqref; sip != NULL; sip = sip->next) {
3317     LookupSegments (NULL, sip, userdata);
3318   }
3319 }
3320 
3321 
3322 static CharPtr inferencePrefix [] = {
3323   "",
3324   "similar to sequence",
3325   "similar to AA sequence",
3326   "similar to DNA sequence",
3327   "similar to RNA sequence",
3328   "similar to RNA sequence, mRNA",
3329   "similar to RNA sequence, EST",
3330   "similar to RNA sequence, other RNA",
3331   "profile",
3332   "nucleotide motif",
3333   "protein motif",
3334   "ab initio prediction",
3335   "alignment",
3336   NULL
3337 };
3338 
3339 
NextColonOrVerticalBarPtr(CharPtr ptr)3340 static CharPtr NextColonOrVerticalBarPtr (CharPtr ptr)
3341 
3342 {
3343   Char  ch = '\0';
3344 
3345   if (ptr == NULL) return NULL;
3346 
3347   ch = *ptr;
3348   while (ch != '\0') {
3349     if (ch == ':' || ch == '|') return ptr;
3350     ptr++;
3351     ch = *ptr;
3352   }
3353 
3354   return NULL;
3355 }
3356 
LookupInference(SeqFeatPtr sfp,Pointer userdata)3357 static void LookupInference (SeqFeatPtr sfp, Pointer userdata)
3358 
3359 {
3360   Int2        accnv, best, j;
3361   Char        ch;
3362   FarIDPtr    fip;
3363   GBQualPtr   gbq;
3364   size_t      len;
3365   CharPtr     nxt;
3366   CharPtr     ptr;
3367   CharPtr     rest;
3368   CharPtr     str;
3369   CharPtr     tmp;
3370   ValNodePtr  vnp;
3371 
3372   if (sfp == NULL || userdata == NULL) return;
3373   fip = (FarIDPtr) userdata;
3374 
3375   for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
3376     if (StringICmp (gbq->qual, "inference") != 0) continue;
3377     if (StringHasNoText (gbq->val)) continue;
3378 
3379     rest = NULL;
3380     best = -1;
3381     for (j = 0; inferencePrefix [j] != NULL; j++) {
3382       len = StringLen (inferencePrefix [j]);
3383       if (StringNICmp (gbq->val, inferencePrefix [j], len) != 0) continue;
3384       rest = gbq->val + len;
3385       best = j;
3386     }
3387     if (best < 0 || inferencePrefix [best] == NULL) continue;
3388     if (rest == NULL) continue;
3389 
3390     ch = *rest;
3391     while (IS_WHITESP (ch)) {
3392       rest++;
3393       ch = *rest;
3394     }
3395     if (StringNICmp (rest, "(same species)", 14) == 0) {
3396       rest += 14;
3397     }
3398     ch = *rest;
3399     while (IS_WHITESP (ch) || ch == ':') {
3400       rest++;
3401       ch = *rest;
3402     }
3403     if (StringHasNoText (rest)) continue;
3404 
3405     str = StringSave (rest);
3406 
3407     ptr = str;
3408     if (best == 12) {
3409       ptr = StringRChr (str, ':');
3410       if (ptr != NULL) {
3411         *ptr = '\0';
3412         ptr++;
3413       }
3414     }
3415     while (ptr != NULL) {
3416       nxt = StringChr (ptr, ',');
3417       if (nxt != NULL) {
3418         *nxt = '\0';
3419         nxt++;
3420       }
3421       tmp = NextColonOrVerticalBarPtr (ptr);
3422       if (tmp != NULL) {
3423         *tmp = '\0';
3424         tmp++;
3425         TrimSpacesAroundString (ptr);
3426         TrimSpacesAroundString (tmp);
3427         if (StringDoesHaveText (tmp)) {
3428           if (StringICmp (ptr, "INSD") == 0 || StringICmp (ptr, "RefSeq") == 0) {
3429             accnv = ValidateAccnDotVer (tmp);
3430             if (accnv == 0) {
3431               ReplaceSpacesWithPluses (tmp);
3432               vnp = ValNodeCopyStr (NULL, 0, tmp);
3433               if (fip->strs == NULL) {
3434                 fip->strs = vnp;
3435               } else {
3436                 vnp->next = fip->strs;
3437                 fip->strs = vnp;
3438               }
3439             }
3440           }
3441         }
3442       }
3443       ptr = nxt;
3444     }
3445 
3446     MemFree (str);
3447   }
3448 }
3449 
3450 
GiExists(BIG_ID gi)3451 static Boolean GiExists (
3452   BIG_ID gi
3453 )
3454 
3455 {
3456   ValNode  vn;
3457 
3458   if (gi < 1) return TRUE;
3459 
3460   vn.choice = SEQID_GI;
3461   vn.data.intvalue = gi;
3462   vn.next = NULL;
3463 
3464   if (BioseqFindCore (&vn) != NULL) return TRUE;
3465 
3466   if (FetchFromSeqIdGiCache (gi, NULL)) return TRUE;
3467 
3468   return FALSE;
3469 }
3470 
3471 
FilterCachedGis(ValNodePtr head)3472 static ValNodePtr FilterCachedGis (
3473   ValNodePtr head
3474 )
3475 
3476 {
3477   ValNodePtr    next;
3478   Pointer PNTR  prev;
3479   ValNodePtr    top;
3480   ValNodePtr    vnp;
3481 
3482   if (head == NULL) return NULL;
3483   top = head;
3484 
3485   prev = (Pointer PNTR) &top;
3486   vnp = top;
3487   while (vnp != NULL) {
3488     next = vnp->next;
3489     if (GiExists (vnp->data.intvalue)) {
3490       *(prev) = next;
3491       vnp->next = NULL;
3492       ValNodeFree (vnp);
3493     } else {
3494       prev = (Pointer PNTR) &(vnp->next);
3495     }
3496     vnp = next;
3497   }
3498 
3499 
3500   return top;
3501 }
3502 
3503 
SipExists(SeqIdPtr sip)3504 static Boolean SipExists (
3505   SeqIdPtr sip
3506 )
3507 
3508 {
3509   if (sip == NULL) return TRUE;
3510 
3511   if (BioseqFindCore (sip) != NULL) return TRUE;
3512 
3513   if (FetchFromGiSeqIdCache (sip, NULL)) return TRUE;
3514 
3515   return FALSE;
3516 }
3517 
3518 
FilterCachedAccns(ValNodePtr head)3519 static ValNodePtr FilterCachedAccns (
3520   ValNodePtr head
3521 )
3522 
3523 {
3524   ValNodePtr    next;
3525   Pointer PNTR  prev;
3526   ValNodePtr    top;
3527   ValNodePtr    vnp;
3528 
3529   if (head == NULL) return NULL;
3530   top = head;
3531 
3532   prev = (Pointer PNTR) &top;
3533   vnp = top;
3534   while (vnp != NULL) {
3535     next = vnp->next;
3536     if (SipExists (vnp->data.ptrvalue)) {
3537       *(prev) = next;
3538       vnp->next = NULL;
3539       ValNodeFree (vnp);
3540     } else {
3541       prev = (Pointer PNTR) &(vnp->next);
3542     }
3543     vnp = next;
3544   }
3545 
3546 
3547   return top;
3548 }
3549 
3550 
FilterCachedStrs(ValNodePtr head)3551 static ValNodePtr FilterCachedStrs (
3552   ValNodePtr head
3553 )
3554 
3555 {
3556   ValNodePtr    next;
3557   Pointer PNTR  prev;
3558   SeqIdPtr      sip;
3559   CharPtr       str;
3560   ValNodePtr    top;
3561   ValNodePtr    vnp;
3562 
3563   if (head == NULL) return NULL;
3564   top = head;
3565 
3566   prev = (Pointer PNTR) &top;
3567   vnp = top;
3568   while (vnp != NULL) {
3569     next = vnp->next;
3570     str = (CharPtr) vnp->data.ptrvalue;
3571     sip = SeqIdFromAccessionDotVersion (str);
3572     if (sip != NULL && SipExists (sip)) {
3573       *(prev) = next;
3574       vnp->next = NULL;
3575       ValNodeFree (vnp);
3576     } else {
3577       prev = (Pointer PNTR) &(vnp->next);
3578     }
3579     SeqIdFree (sip);
3580     vnp = next;
3581   }
3582 
3583 
3584   return top;
3585 }
3586 
3587 
SeqIdSortCompare(SeqIdPtr sip1,SeqIdPtr sip2)3588 static int SeqIdSortCompare (SeqIdPtr sip1, SeqIdPtr sip2)
3589 
3590 {
3591   TextSeqIdPtr  tsip1, tsip2;
3592 
3593   if (sip1 == NULL || sip2 == NULL) return 0;
3594 
3595   if (sip1->choice > sip2->choice) {
3596     return 1;
3597   } else if (sip1->choice < sip2->choice) {
3598     return -1;
3599   }
3600 
3601   switch (sip1->choice) {
3602     case SEQID_GENBANK :
3603     case SEQID_EMBL :
3604     case SEQID_DDBJ :
3605     case SEQID_TPG :
3606     case SEQID_TPE :
3607     case SEQID_TPD :
3608     case SEQID_OTHER :
3609     case SEQID_GPIPE :
3610       tsip1 = (TextSeqIdPtr) sip1->data.ptrvalue;
3611       tsip2 = (TextSeqIdPtr) sip2->data.ptrvalue;
3612       if (tsip1 == NULL || tsip2 == NULL) return 0;
3613       if (StringDoesHaveText (tsip1->accession) && StringDoesHaveText (tsip2->accession)) {
3614         return StringICmp (tsip1->accession, tsip2->accession);
3615       }
3616       if (StringDoesHaveText (tsip1->name) && StringDoesHaveText (tsip2->name)) {
3617         return StringICmp (tsip1->name, tsip2->name);
3618       }
3619       break;
3620     default :
3621       break;
3622   }
3623 
3624   return 0;
3625 }
3626 
3627 
SortVnpBySeqId(VoidPtr ptr1,VoidPtr ptr2)3628 static int LIBCALLBACK SortVnpBySeqId (VoidPtr ptr1, VoidPtr ptr2)
3629 
3630 {
3631  SeqIdPtr    sip1, sip2;
3632   ValNodePtr  vnp1, vnp2;
3633 
3634   if (ptr1 == NULL || ptr2 == NULL) return 0;
3635   vnp1 = *((ValNodePtr PNTR) ptr1);
3636   vnp2 = *((ValNodePtr PNTR) ptr2);
3637   if (vnp1 == NULL || vnp2 == NULL) return 0;
3638   sip1 = (SeqIdPtr) vnp1->data.ptrvalue;
3639   sip2 = (SeqIdPtr) vnp2->data.ptrvalue;
3640   if (sip1 == NULL || sip2 == NULL) return 0;
3641   return SeqIdSortCompare (sip1, sip2);
3642 }
3643 
3644 
UniqueSeqIdValNode(ValNodePtr list)3645 static ValNodePtr UniqueSeqIdValNode (ValNodePtr list)
3646 
3647 {
3648   SeqIdPtr      curr;
3649   SeqIdPtr      last;
3650   ValNodePtr    next;
3651   Pointer PNTR  prev;
3652   ValNodePtr    vnp;
3653 
3654   if (list == NULL) return NULL;
3655   last = (SeqIdPtr) list->data.ptrvalue;
3656   vnp = list->next;
3657   prev = (Pointer PNTR) &(list->next);
3658   while (vnp != NULL) {
3659     next = vnp->next;
3660     curr = (SeqIdPtr) vnp->data.ptrvalue;
3661     if (SeqIdSortCompare (last, curr) == 0) {
3662       vnp->next = NULL;
3663       *prev = next;
3664       ValNodeFree (vnp);
3665     } else {
3666       last = (SeqIdPtr) vnp->data.ptrvalue;
3667       prev = (Pointer PNTR) &(vnp->next);
3668     }
3669     vnp = next;
3670   }
3671 
3672   return list;
3673 }
3674 
3675 
GiRevHistLookupFarSeqIDs(SeqEntryPtr sep,Boolean components,Boolean locations,Boolean products,Boolean alignments,Boolean history,Boolean inference,Boolean others)3676 NLM_EXTERN Int4 LIBCALLBACK GiRevHistLookupFarSeqIDs (
3677   SeqEntryPtr sep,
3678   Boolean components,
3679   Boolean locations,
3680   Boolean products,
3681   Boolean alignments,
3682   Boolean history,
3683   Boolean inference,
3684   Boolean others
3685 )
3686 
3687 {
3688   CharPtr       accn;
3689   CharPtr PNTR  accns;
3690   Char          buf [64];
3691   BIG_ID        gi;
3692   BIG_ID_PNTR   gis;
3693   FarIdData     fid;
3694   Int4          i, num, total = 0;
3695   SeqIdPtr      sip;
3696   ValNodePtr    vnp;
3697   SeqEntryPtr   oldsep;
3698 
3699   if (sep == NULL) return 0;
3700   MemSet ((Pointer) &fid, 0, sizeof (FarIdData));
3701 
3702   oldsep = SeqEntrySetScope (sep);
3703 
3704   if (components) {
3705     VisitBioseqsInSep (sep, (Pointer) &fid, LookupBioseqs);
3706   }
3707   if (locations) {
3708     VisitFeaturesInSep (sep, (Pointer) &fid, LookupLocations);
3709   }
3710   if (products) {
3711     VisitFeaturesInSep (sep, (Pointer) &fid, LookupProducts);
3712   }
3713   if (alignments) {
3714     VisitAlignmentsInSep (sep, (Pointer) &fid, LookupAlignments);
3715   }
3716   if (history) {
3717     VisitBioseqsInSep (sep, (Pointer) &fid, LookupHistory);
3718   }
3719   if (inference) {
3720     VisitFeaturesInSep (sep, (Pointer) &fid, LookupInference);
3721   }
3722   if (others) {
3723     VisitDescriptorsInSep (sep, (Pointer) &fid, LookupOthers);
3724   }
3725 
3726   if (fid.gis != NULL) {
3727     fid.gis = ValNodeSort (fid.gis, SortByIntvalue);
3728     fid.gis = UniqueIntValNode (fid.gis);
3729     fid.gis = FilterCachedGis (fid.gis);
3730     num = ValNodeLen (fid.gis);
3731 
3732     if (num > 0) {
3733       gis = (BIG_ID_PNTR) MemNew (sizeof (BIG_ID) * (num + 2));
3734       if (gis != NULL) {
3735         for (vnp = fid.gis, i = 0; vnp != NULL; vnp = vnp->next, i++) {
3736           gi = (BIG_ID) vnp->data.intvalue;
3737           if (gi < 1) continue;
3738           gis [i] = gi;
3739         }
3740         total += GiRevHistPreLoadSeqIdGiCacheEx (num, gis, FALSE);
3741         MemFree (gis);
3742       }
3743     }
3744   }
3745 
3746   if (fid.accns != NULL) {
3747     fid.accns = ValNodeSort (fid.accns, SortVnpBySeqId);
3748     fid.accns = UniqueSeqIdValNode (fid.accns);
3749     fid.accns = FilterCachedAccns (fid.accns);
3750     for (vnp = fid.accns; vnp != NULL; vnp = vnp->next) {
3751       sip = (SeqIdPtr) vnp->data.ptrvalue;
3752       if (sip == NULL) continue;
3753       SeqIdWrite (sip, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 1);
3754       ReplaceSpacesWithPluses (buf);
3755       vnp->data.ptrvalue = StringSave (buf);
3756     }
3757     num = ValNodeLen (fid.accns);
3758 
3759     if (num > 0) {
3760       accns = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (num + 2));
3761       if (accns != NULL) {
3762         for (vnp = fid.accns, i = 0; vnp != NULL; vnp = vnp->next, i++) {
3763           accn = (CharPtr) vnp->data.ptrvalue;
3764           if (StringHasNoText (accn)) continue;
3765           accns [i] = accn;
3766         }
3767         total += AccnListPreLoadSeqIdGiCache (accns);
3768         MemFree (accns);
3769       }
3770     }
3771 
3772     for (vnp = fid.accns; vnp != NULL; vnp = vnp->next) {
3773       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
3774     }
3775   }
3776 
3777   if (fid.strs != NULL) {
3778     fid.strs = ValNodeSort (fid.strs, SortVnpByString);
3779     fid.strs = UniqueValNode (fid.strs);
3780     fid.strs = FilterCachedStrs (fid.strs);
3781     num = ValNodeLen (fid.strs);
3782 
3783     if (num > 0) {
3784       accns = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (num + 2));
3785       if (accns != NULL) {
3786         for (vnp = fid.strs, i = 0; vnp != NULL; vnp = vnp->next, i++) {
3787           accn = (CharPtr) vnp->data.ptrvalue;
3788           if (StringHasNoText (accn)) continue;
3789           accns [i] = accn;
3790         }
3791         total += AccnListPreLoadSeqIdGiCache (accns);
3792         MemFree (accns);
3793       }
3794     }
3795 
3796     for (vnp = fid.strs; vnp != NULL; vnp = vnp->next) {
3797       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
3798     }
3799   }
3800 
3801   ValNodeFree (fid.gis);
3802   ValNodeFree (fid.accns);
3803   ValNodeFree (fid.strs);
3804 
3805   SeqEntrySetScope (oldsep);
3806   return total;
3807 }
3808 
3809 
GiRevHistLookupSeqIdSet(BIG_ID gi)3810 NLM_EXTERN SeqIdPtr LIBCALLBACK GiRevHistLookupSeqIdSet (
3811     BIG_ID gi
3812 )
3813 
3814 {
3815   return GiSeqIdSetSynchronousQuery (gi);
3816 }
3817 
3818 
3819 /* PubMed fetch functions */
3820 
DoPubMedFetch(Int4 uid)3821 static PubmedEntryPtr LIBCALLBACK DoPubMedFetch (Int4 uid)
3822 
3823 {
3824   return PubMedSynchronousQuery (uid);
3825 }
3826 
3827 
PubMedFetchEnable(void)3828 NLM_EXTERN Boolean PubMedFetchEnable (
3829   void
3830 )
3831 
3832 {
3833   PubMedSetFetchFunc (DoPubMedFetch);
3834   return TRUE;
3835 }
3836 
3837 
PubMedFetchDisable(void)3838 NLM_EXTERN void PubMedFetchDisable (
3839   void
3840 )
3841 
3842 {
3843   PubMedSetFetchFunc (NULL);
3844 }
3845