1 /* accentr.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
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 have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * RCS $Id: accentr.c,v 6.10 2005/06/06 18:45:47 kans Exp $
27 *
28 * Author: Ostell
29 *
30 * Version Creation Date: 4/23/92
31 *
32 * File Description:
33 * entrez index access library for Entrez
34 *
35 * Modifications:
36 * --------------------------------------------------------------------------
37 * Date Name Description of modification
38 * ------- ---------- -----------------------------------------------------
39 * 08-16-94 Brylawski Added access to mesh term explosion, mesh tree browsing,
40 * and on-the-fly neighboring.
41 *
42 * 10-06-94 Schuler Added EntrezBiostrucGet() function
43 *
44 * 11-20-94 Brylawski Permitted client to modify on-the-fly neighboring
45 * via .entrezrc parameters
46 *
47 * 05-19-95 Schuler Added rcs Log directive for automatic insertion of
48 * modification comments.
49 *
50 * $Log: accentr.c,v $
51 * Revision 6.10 2005/06/06 18:45:47 kans
52 * post warning message if obsolete EntrezInit function is called
53 *
54 * Revision 6.9 2001/09/04 23:28:55 juran
55 * Always assume network access in Mac OS.
56 *
57 * Revision 6.8 2001/08/16 19:40:33 kans
58 * reverted to not assume network - UNIX still does cdrom access compile - and cleaned up junk in log instructions
59 *
60 * Revision 6.7 2001/08/15 20:57:07 juran
61 * Always assume network access.
62 *
63 * Revision 6.6 2000/01/12 20:17:12 vakatov
64 * Get rid of the LIBCALL specifier at EntrezSeqEntryGet()
65 *
66 * Revision 6.5 1999/01/06 14:18:35 grisha
67 * add defines to switch ID0/ID1 usage
68 *
69 * Revision 6.4 1998/12/08 20:38:47 kans
70 * EntrezGIForSeqIdFunc aborts on local, other, general, gi, notset before connecting to Entrez network server
71 *
72 * Revision 6.3 1998/06/12 19:19:06 kans
73 * fixed unix compiler warnings
74 *
75 * Revision 6.2 1998/02/23 17:59:38 kans
76 * mesh and taxonomy hierarchy modes both call NetEntHierarchyGet(term,db,fld)
77 *
78 * Revision 6.1 1997/09/19 13:16:19 kans
79 * removed or ifdef unused variables
80 *
81 * Revision 6.0 1997/08/25 18:12:26 madden
82 * changed to 6.0
83 *
84 * Revision 5.38 1997/07/28 13:30:35 ostell
85 * Moved GetUniGeneIDForSeqId() to seqmgr.c
86 *
87 * Revision 5.37 1997/07/09 19:25:57 kuzio
88 * kludge for corn; and tidied NCBICG
89 *
90 * Revision 5.36 1997/06/26 21:55:10 vakatov
91 * [PC] DLL'd "ncbicdr.lib", "ncbiacc.lib", "ncbinacc.lib" and "ncbicacc.lib"
92 *
93 * Revision 5.35 1997/05/22 20:35:44 epstein
94 * add error strings when fetching Medline and Sequence entries, to identify which UID encountered the problem
95 *
96 * Revision 5.34 1997/04/18 16:01:08 shavirin
97 * Removed annoying compiler messages "Statement not reached"
98 *
99 * Revision 5.33 1997/03/17 16:26:23 brandon
100 * added PMEntrezDetailedInfo
101 *
102 * Revision 5.32 1997/03/13 15:37:14 brandon
103 * added support for retcodes in PmEntrezsequencegets
104 *
105 * Revision 5.31 1997/02/24 17:27:14 brandon
106 * added support for PubMed SeqId functions.
107 *
108 * Revision 5.30 1997/02/24 16:47:51 brandon
109 * added support for named uid lists.
110 *
111 * Revision 5.29 1997/02/19 16:28:29 brandon
112 * fixed EntrezSeqEntryListGet for PM
113 *
114 * Revision 5.28 1997/02/10 20:35:35 brandon
115 * fixed EntrezSeqEntryGet for PMEntrez
116 *
117 * Revision 5.27 1997/02/05 15:53:14 brandon
118 * added PMEntSeqEntryListGet
119 *
120 * Revision 5.26 1997/02/04 15:29:27 brandon
121 * fixed typo
122 *
123 * Revision 5.25 1997/02/03 19:36:48 brandon
124 * added line for PMEntrezHierarchyGet
125 *
126 * Revision 5.24 1997/01/24 22:26:21 kuzio
127 * NCBICG 9000000 kludge
128 *
129 * Revision 5.23 1997/01/23 17:07:19 brandon
130 * modified EntrezTLFree
131 *
132 * Revision 5.22 1997/01/19 15:39:45 brandon
133 * *** empty log message ***
134 *
135 * Revision 5.21 1997/01/16 18:17:43 brandon
136 * added SelectDataSource wrapper
137 *
138 * Revision 5.20 1997/01/14 18:39:16 brandon
139 * added wrapper function GetCurMediaType()
140 *
141 * Revision 5.19 1997/01/13 21:34:02 brandon
142 * *** empty log message ***
143 *
144 * Revision 5.18 1996/12/23 17:50:38 brandon
145 * modified EntrezInit
146 *
147 * Revision 5.17 1996/12/23 04:25:48 brandon
148 * *** empty log message ***
149 *
150 * Revision 5.16 1996/12/23 02:02:29 brandon
151 * *** empty log message ***
152 *
153 * Revision 5.15 1996/12/23 02:00:35 brandon
154 * modified PMAdjustEntrezInfo
155 *
156 * Revision 5.14 1996/12/04 15:06:32 epstein
157 * restore network fetching of MEDLINE entries (accidentally deleted in version 5.12
158 *
159 * Revision 5.13 1996/12/03 19:52:11 brandon
160 * added ifdefs for pubmed
161 *
162 * Revision 5.12 1996/12/02 22:24:02 brandon
163 * *** empty log message ***
164 *
165 * Revision 5.11 1996/12/02 22:10:08 brandon
166 * *** empty log message ***
167 *
168 * Revision 5.10 1996/09/13 14:43:17 brandon
169 * modifed pubmed routines
170 *
171 * Revision 5.9 1996/08/30 16:32:58 brandon
172 * fixed PM links
173 *
174 * Revision 5.8 1996/08/14 19:55:53 epstein
175 * add APIs for fetching pieces of biostruc annots
176 *
177 * Revision 5.7 1996/08/14 17:08:29 brandon
178 * *** empty log message ***
179 *
180 * Revision 5.5 1996/08/14 15:15:05 brandon
181 * added date parameter to tleval functions
182 *
183 * Revision 5.4 1996/07/30 15:28:28 epstein
184 * correct logic when retrieving docsums
185 *
186 * Revision 5.3 1996/07/30 15:27:14 epstein
187 * add kludge for retrieving docsums from ID
188 *
189 * Revision 5.2 1996/07/26 20:28:03 epstein
190 * remove special casing of FLD_PROT for PubMed
191 *
192 * Revision 5.1 1996/07/26 20:19:34 zjing
193 * fix in EntrezBioseqFetchFunc for gis of segmented sequence
194 *
195 * Revision 5.0 1996/05/28 13:55:34 ostell
196 * Set to revision 5.0
197 *
198 * Revision 4.26 1996/05/15 15:03:09 kans
199 * added a conditional to suppress an unused variable warning
200 *
201 * Revision 4.25 1996/05/10 19:35:00 epstein
202 * add Pubmed support
203 *
204 *
205 * Revision 4.24 1996/05/02 20:56:08 epstein
206 * fix logic of obtaining entries from ID server
207 *
208 * Revision 4.23 1996/04/18 16:51:38 kuzio
209 * add KLUDGE_YGG
210 *
211 * Revision 4.22 1996/04/10 14:17:55 ostell
212 * reverted Kludge CEGC to original CESC
213 *
214 * Revision 4.19 1996/03/29 18:52:44 epstein
215 * add support for structure alignments
216 *
217 * Revision 4.18 1996/03/28 21:23:42 epstein
218 * move ID-backending from srventr into accentr
219 *
220 * Revision 4.17 1996/03/26 16:29:40 epstein
221 * migrate byte-swapping functions to ncbimisc.[ch]
222 *
223 * Revision 4.16 1996/03/15 02:46:44 ostell
224 * added Check to EntrezGIForSeqID() to remove calls for SeqId types that
225 * will not be satisfied.
226 *
227 * Revision 4.15 1996/03/11 21:51:03 ostell
228 * made GetUniGeneIDForSeqId() externally visible
229 *
230 * Revision 4.14 1996/02/21 20:29:43 ostell
231 * added KLUDGE_HUMGEN
232 *
233 * Revision 4.13 1996/02/16 16:32:40 kans
234 * CESC and BSNR kludges, allow UniGene as well as UNIGENE
235 *
236 * Revision 4.12 1995/12/05 00:56:43 ostell
237 * fixed UniGene fetch problem in Fetch
238 *
239 * Revision 4.10 1995/10/19 20:27:49 epstein
240 * correct EntrezInit/EntrezFini logic (again)
241 *
242 * Revision 4.9 1995/10/11 13:39:20 epstein
243 * add EntrezIsInited() function
244 *
245 * Revision 4.8 1995/10/02 15:27:11 epstein
246 * add range-checking for Net and MB
247 *
248 * Revision 4.6 1995/09/26 21:41:45 ostell
249 * set hierHead to NULL after freeing data in FreeHierarchyList()
250 *
251 * Revision 4.5 1995/08/28 18:50:12 epstein
252 * more protection against multiple EntrezFini calls
253 *
254 * Revision 4.4 1995/08/25 20:22:00 epstein
255 * add counter to avoid unnecessary EntrezInits
256 *
257 * Revision 4.3 1995/08/22 19:37:02 epstein
258 * add network-based clustering support
259 *
260 * Revision 4.1 1995/08/11 20:25:38 epstein
261 * add max-models support for biostrucs
262 *
263 * Revision 4.0 1995/07/26 13:50:32 ostell
264 * force revision to 4.0
265 *
266 * Revision 2.71 1995/07/25 18:47:57 kans
267 * revert to no Biostruc_supported
268 *
269 * Revision 2.70 1995/07/11 14:53:39 epstein
270 * move DocSumFree to objentr.c
271 *
272 * Revision 2.69 1995/06/29 15:57:51 epstein
273 * added Complexity argument when fetching structures
274 *
275 * Revision 2.68 95/06/20 15:42:45 epstein
276 * add support for BigMed-based Entrez API
277 *
278 * Revision 2.67 95/06/19 16:42:25 ostell
279 * added fake_seqid in EntrezBioseqFetch. When "sip" was used in
280 * BioseqFindInSeqEntry() call, it was not initialized in the case of a
281 * previously cached SeqEntry (only gi set).
282 *
283 * Revision 2.66 1995/05/24 17:14:41 ostell
284 * added code to maintain connection through multiple nested calles to
285 * EntrezBioseqFetchEnable and Disable
286 *
287 * Revision 2.65 1995/05/16 14:36:20 schuler
288 * Automatic comment insertion enabled
289 *
290 *
291 *
292 * ==========================================================================
293 */
294
295 #define REVISION_STR "$Revision: 6.10 $"
296
297 #include <accentr.h>
298 #include <seqmgr.h>
299 #include <sequtil.h>
300
301 #include <cdconfig.h>
302 /* Must not assume network - unused cdromlib stuff is still tangled in */
303 /* Okay to assume network in Mac OS. */
304 #ifdef __MACOS__
305 #define _NETENT_
306 #endif
307 #ifdef _NETENT_
308 #include <netentr.h> /* support network access */
309 #else
310 #ifdef _MBENTREZ_
311 #include <mbentrez.h>
312 #define USE_ID0 1
313 #define USE_IDxARCH 1
314 #endif
315 #ifdef _PMENTREZ_
316 #include <pmentrez.h>
317 #define USE_ID1 1
318 #define USE_IDxARCH 1
319 #endif
320 #ifdef USE_ID0
321 #include <id0arch.h>
322 #endif
323 #ifdef USE_ID1
324 #include <id1arch.h>
325 #endif
326 #ifndef _CDENTREZ_
327 #include <cdentrez.h> /* support cdrom access */
328 #endif
329 #endif /* _NETENT_ */
330
331 #ifdef _NET_AND_CD_
332 #include <netentr.h> /* support network access */
333 #endif /* _NET_AND_CD_ */
334
335 #define MAX_SECS_IN_ADAPTIVE_MATRIX 3
336 #define MAX_CHUNK_IN_ADAPTIVE_MATRIX 12
337 #define ADAPTIVE_MATRIX_INITIAL_CONDITION 8
338
339 #define HIERARCHY_CACHE_SIZE 200
340
341 #ifdef USE_IDxARCH
342 #ifdef USE_ID0
343 #define IDxArchInit ID0ArchInit
344 #define IDxArchFini ID0ArchFini
345 #define IDxArchSeqEntryGet ID0ArchSeqEntryGet
346 #define IDxArchGIGet ID0ArchGIGet
347 #endif
348 #ifdef USE_ID1
349 #define IDxArchInit ID1ArchInit
350 #define IDxArchFini ID1ArchFini
351 #define IDxArchSeqEntryGet ID1ArchSeqEntryGet
352 #define IDxArchGIGet ID1ArchGIGet
353 #endif
354 #endif /* USE_IDxARCH */
355
356 #ifdef _NETENTREZ_
357 Uint1 AdaptiveDocSumMatrix[MAX_CHUNK_IN_ADAPTIVE_MATRIX+1][MAX_SECS_IN_ADAPTIVE_MATRIX+1] = {
358 8, 6, 3, 3,
359 8, 6, 3, 3,
360 8, 6, 3, 3,
361 8, 6, 3, 3,
362 9, 7, 4, 3,
363 9, 8, 5, 3,
364 10, 9, 5, 3,
365 10, 10, 5, 3,
366 11, 10, 5, 3,
367 11, 11, 5, 3,
368 12, 11, 5, 3,
369 12, 11, 5, 3,
370 12, 11, 5, 3
371 };
372 #endif /* _NETENTREZ_ */
373
374 /* maximum link records returned */
375 static Int4 MaxLinks = (Int4)(INT2_MAX / sizeof(DocUid));
376
377 static DocUidPtr queueduids = NULL; /* Used to queue CD-ROM uid query list */
378 static DocSumPtr PNTR queuedsums = NULL; /* Used to queue network retrieved DocSums */
379 static Int2 numqueued = 0;
380 static DocType queuedtype;
381 static CharPtr CombinedInfo = NULL;
382 static DocType lastTermType;
383 static Int2 lastBooleanMediaType;
384 static Int2 entrezInitCount = 0;
385 #ifdef USE_IDxARCH
386 static Boolean idConnected = FALSE;
387 static Boolean idCantConnect= FALSE;
388 static void DisconnID(void);
389 #endif
390
391
GetCurMediaType(void)392 static Int2 GetCurMediaType(void)
393 {
394 #ifdef _PMENTREZ_
395 return MEDIUM_DISK;
396 #else
397 return CurMediaType();
398 #endif
399 }
400
DoSelectDataSource(CharPtr section,CharPtr field1,CharPtr field2)401 static Boolean LIBCALL DoSelectDataSource(CharPtr section, CharPtr field1, CharPtr field2)
402 {
403 #ifdef _PMENTREZ_
404 return TRUE;
405 #else
406 return SelectDataSource (section, field1, field2);
407 #endif
408 }
409
DoSelectDataSourceByType(DocType type,CharPtr field1,CharPtr field2)410 static Boolean LIBCALL DoSelectDataSourceByType(DocType type, CharPtr field1, CharPtr field2)
411 {
412 #ifdef _PMENTREZ_
413 return TRUE;
414 #else
415 return SelectDataSourceByType(type, field1, field2);
416 #endif
417 }
418
419 /*****************************************************************************
420 *
421 * EntrezInit ()
422 *
423 *****************************************************************************/
424
EntrezInit(CharPtr appl_id,Boolean no_warnings,BoolPtr is_network)425 NLM_EXTERN Boolean LIBCALL EntrezInit (CharPtr appl_id, Boolean no_warnings, BoolPtr is_network)
426
427 {
428 Boolean cdretval = FALSE;
429 Boolean netretval = FALSE;
430 Boolean mbretval = TRUE;
431 queueduids = NULL;
432 queuedsums = NULL;
433 numqueued = 0;
434
435 Message (MSG_POSTERR, "The Entrez1 service is obsolete and unsupported. Please switch to using EntrezSynchronousQuery in the future.");
436
437 if (is_network != NULL)
438 {
439 *is_network = FALSE;
440 }
441
442 if (entrezInitCount > 0)
443 {
444 entrezInitCount++;
445 return TRUE;
446 }
447
448 #ifdef _PMENTREZ_
449 mbretval = PMEntrezInit(no_warnings);
450 #else
451
452 #ifdef _CDENTREZ_
453 cdretval = CdEntrezInit(no_warnings);
454 #endif
455
456 #ifdef _MBENTREZ_
457 mbretval = MBEntrezInit(no_warnings);
458 #endif
459
460 #endif
461
462 #ifdef _NETENTREZ_
463 if (is_network != NULL)
464 {
465 *is_network = TRUE;
466 }
467
468 netretval = NetEntrezInit(appl_id, no_warnings);
469
470 #endif
471
472 #ifdef _PMENTREZ_
473
474 MaxLinks = INT4_MAX;
475
476 #else
477
478 if (!cdretval && !netretval)
479 { /* partial success (one of two) is O.K. */
480 return FALSE;
481 }
482
483 MaxLinks = EntrezGetMaxLinks();
484
485 #endif
486
487 if (mbretval)
488 entrezInitCount++;
489 return mbretval;
490 }
491
492 /*****************************************************************************
493 *
494 * EntrezIsInited ()
495 *
496 *****************************************************************************/
EntrezIsInited(void)497 NLM_EXTERN Boolean LIBCALL EntrezIsInited(void)
498 {
499 return (entrezInitCount > 0);
500 }
501
502 /*****************************************************************************
503 *
504 * EntrezFini ()
505 *
506 *****************************************************************************/
507
ClearQueuedDocSums(void)508 static void ClearQueuedDocSums (void)
509
510 {
511 Int2 i;
512
513 if (queueduids != NULL) {
514 queueduids = (DocUidPtr) MemFree (queueduids);
515 }
516 if (queuedsums != NULL) {
517 for (i = 0; i < numqueued; i++) {
518 if (queuedsums [i] != NULL) {
519 queuedsums [i] = DocSumFree (queuedsums [i]);
520 }
521 }
522 queuedsums = (DocSumPtr PNTR) MemFree (queuedsums);
523 }
524 numqueued = 0;
525 }
526
527 static void FreeHierarchyList PROTO((void));
528
EntrezFini(void)529 NLM_EXTERN void LIBCALL EntrezFini (void)
530
531 {
532 ClearQueuedDocSums ();
533 FreeHierarchyList ();
534 if (CombinedInfo != NULL)
535 {
536 CombinedInfo = (CharPtr) MemFree(CombinedInfo);
537 }
538
539 if (entrezInitCount <= 0)
540 return;
541 if (--entrezInitCount > 0)
542 return;
543
544 #ifdef USE_IDxARCH
545 DisconnID ();
546 #endif
547 #ifdef _CDENTREZ_
548 CdEntrezFini();
549 #endif
550 #ifdef _MBENTREZ_
551 MBEntrezFini();
552 #endif
553 #ifdef _PMENTREZ_
554 PMEntrezFini();
555 #endif
556 #ifdef _NETENTREZ_
557 NetEntrezFini();
558 #endif
559 }
560
561 /*****************************************************************************
562 *
563 * EntrezInfoPtr EntrezGetInfo()
564 *
565 *****************************************************************************/
EntrezGetInfo(void)566 NLM_EXTERN EntrezInfoPtr LIBCALL EntrezGetInfo (void)
567
568 {
569 static EntrezInfoPtr cip = NULL;
570
571 #if defined(_CDENTREZ_) && (defined(_MBENTREZ_) || defined(_PMENTREZ_))
572 #ifdef _MBENTREZ_
573 return MBAdjustEntrezInfo (CdEntrezGetInfo());
574 #else
575 return PMEntrezGetInfo();
576 #endif
577 #else
578 if (cip == NULL)
579 cip = EntrezInfoMerge();
580
581 /* as a last resort, fall back on the old, faithful function */
582 if (cip == NULL)
583 #ifdef _CDENTREZ_
584 return CdEntrezGetInfo();
585 #else
586 return NetEntrezGetInfo();
587 #endif
588 else
589 return cip;
590 #endif
591 }
592
593 /*****************************************************************************
594 *
595 * CharPtr EntrezDetailedInfo()
596 * returns either NULL (if no info is available), or a pointer to a
597 * statically allocated string containing formatted status information
598 *
599 *****************************************************************************/
EntrezDetailedInfo(void)600 NLM_EXTERN CharPtr LIBCALL EntrezDetailedInfo (void)
601
602 {
603 CharPtr cdinfo = NULL;
604 CharPtr netinfo = NULL;
605 CharPtr extrainfo = NULL;
606 Int2 extrainfoLen = 0;
607 DocType db;
608 CharPtr str;
609 EntrezInfoPtr eip;
610
611 #ifdef _PMENTREZ_
612 cdinfo = PMEntrezDetailedInfo();
613 #endif
614
615 #ifdef _CDENTREZ_
616 cdinfo = CdEntrezDetailedInfo();
617 #endif
618 #ifdef _NETENTREZ_
619 netinfo = NetEntrezDetailedInfo();
620 #endif
621 if ((eip = EntrezGetInfo()) != NULL)
622 {
623 extrainfo = MemNew(StringLen(eip->descr) + 400);
624 StrCpy(extrainfo, "\n\nCURRENT MEDIA\n ");
625 StrCat(extrainfo, eip->descr);
626 extrainfoLen = StringLen(extrainfo);
627 sprintf(&extrainfo[extrainfoLen], "\n Version %ld.%ld",
628 (long) eip->version, (long) eip->issue);
629 extrainfoLen = StringLen(extrainfo);
630 if (eip->types != NULL)
631 {
632 for (db = 0; db < eip->type_count; db++)
633 {
634 if (eip->types[0].num > 0)
635 {
636 if (eip->type_info != NULL)
637 {
638 str = eip->type_info[db].name;
639 } else {
640 str = eip->type_names[db];
641 }
642 sprintf(&extrainfo[extrainfoLen], "\n # %s entries = %ld",
643 str, (long) (eip->types[db].num));
644 extrainfoLen = StringLen(extrainfo);
645 }
646 }
647 }
648 StrCat(extrainfo, "\n");
649 extrainfoLen = StringLen(extrainfo);
650 }
651
652 if (CombinedInfo != NULL)
653 MemFree(CombinedInfo);
654 if ((CombinedInfo = MemNew(StringLen(cdinfo) + StringLen(netinfo) + 4 + extrainfoLen)) == NULL)
655 {
656 MemFree(extrainfo);
657 return cdinfo; /* better than nothing */
658 }
659 StringCpy(CombinedInfo, cdinfo);
660 StringCat(CombinedInfo, "\n\n");
661 StringCat(CombinedInfo, netinfo);
662 StringCat(CombinedInfo, extrainfo);
663 MemFree(extrainfo);
664
665 return CombinedInfo;
666 }
667
668 /*****************************************************************************
669 *
670 * EntrezGetMaxLinks()
671 * returns max links in link set allowed by system
672 *
673 *****************************************************************************/
EntrezGetMaxLinks(void)674 NLM_EXTERN Int4 LIBCALL EntrezGetMaxLinks (void)
675
676 {
677 Int4 maxlinks = INT4_MAX;
678 Int4 links = 0;
679 Boolean cdSelected = FALSE;
680
681 if (! DoSelectDataSource(ENTR_LINKS_CHAN, "INFO", NULL))
682 {
683 /* ERROR, data unobtainable */
684 return -1;
685 }
686
687 do {
688 switch (GetCurMediaType()) {
689 #ifdef _CDENTREZ_
690 case MEDIUM_CD:
691 /* for ergonomics, check a maximum of one CD */
692 cdSelected = TRUE;
693 /* no break */
694 case MEDIUM_DISK:
695 links = CdEntGetMaxLinks();
696 break;
697 #endif
698 #ifdef _NETENTREZ_
699 case MEDIUM_NETWORK:
700 links = NetEntGetMaxLinks();
701 break;
702 #endif
703 default:
704 break;
705 }
706 maxlinks = MIN(maxlinks, links);
707 } while (!cdSelected && SelectNextDataSource());
708
709 if (maxlinks == INT4_MAX)
710 maxlinks = -1;
711 return maxlinks;
712 }
713
714 /*****************************************************************************
715 *
716 * EntrezSetUserMaxLinks(num)
717 * user settable maximum
718 * can't be > EntrezGetMaxLinks()
719 *
720 *****************************************************************************/
EntrezSetUserMaxLinks(Int4 num)721 NLM_EXTERN Int4 LIBCALL EntrezSetUserMaxLinks (Int4 num)
722
723 {
724 Int4 big;
725
726 big = EntrezGetMaxLinks();
727 if (big < num)
728 num = big;
729 MaxLinks = num;
730 return num;
731 }
732
733 /*****************************************************************************
734 *
735 * EntrezGetUserMaxLinks()
736 * returns current value of MaxLinks
737 *
738 *****************************************************************************/
EntrezGetUserMaxLinks(void)739 NLM_EXTERN Int4 LIBCALL EntrezGetUserMaxLinks (void)
740
741 {
742 return MaxLinks;
743 }
744
745 /*****************************************************************************
746 *
747 * EntrezCreateNamedUidList(term, type, field, num, uids)
748 * Creates a term node in the entrez set structure if one does not
749 * yet exist, and loads the posting file from the uid parameter.
750 *
751 *****************************************************************************/
EntrezCreateNamedUidList(CharPtr term,DocType type,DocField field,Int4 num,DocUidPtr uids)752 NLM_EXTERN void LIBCALL EntrezCreateNamedUidList (CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids)
753
754 {
755
756 #ifdef _PMENTREZ_
757 PMEntrezCreateNamedUIDList(term,type,num,uids);
758 return;
759 #else
760
761 if (! DoSelectDataSourceByType(type, "TERMS", NULL))
762 {
763 return;
764 }
765
766 switch (GetCurMediaType ()) {
767 #ifdef _CDENTREZ_
768 case MEDIUM_CD:
769 case MEDIUM_DISK:
770 CdEntrezCreateNamedUidList (term, type, field, num, uids);
771 break;
772 #endif
773 #ifdef _NETENTREZ_
774 case MEDIUM_NETWORK:
775 NetEntrezCreateNamedUidList (term, type, field, num, uids);
776 break;
777 #endif
778 default:
779 break;
780 }
781 #endif /* _PMENTREZ_ */
782 }
783
784 /*****************************************************************************
785 *
786 * EntrezCreateNamedUidListX(term, type, field, bsp)
787 * Creates a term node in the entrez set structure if one does not
788 * yet exist, and loads the posting file from the uid parameter.
789 *
790 *****************************************************************************/
EntrezCreateNamedUidListX(CharPtr term,DocType type,DocField field,ByteStorePtr bsp)791 NLM_EXTERN void LIBCALL EntrezCreateNamedUidListX (CharPtr term, DocType type, DocField field, ByteStorePtr bsp)
792
793 {
794
795 #ifdef _PMENTREZ_
796 PMEntrezCreateNamedUIDListBSP(term,type,bsp);
797 return;
798 #else
799
800 if (! DoSelectDataSourceByType(type, "TERMS", NULL))
801 {
802 return;
803 }
804
805 switch (GetCurMediaType ()) {
806 #ifdef _CDENTREZ_
807 case MEDIUM_CD:
808 case MEDIUM_DISK:
809 CdEntrezCreateNamedUidListX (term, type, field, bsp);
810 break;
811 #endif
812 #ifdef _NETENTREZ_
813 case MEDIUM_NETWORK:
814 NetEntrezCreateNamedUidListX (term, type, field, bsp);
815 break;
816 #endif
817 default:
818 break;
819 }
820 #endif /* _PMENTREZ_ */
821 }
822
823
824 /*****************************************************************************
825 *
826 * EntrezTLNew (type)
827 * Creates linked list of asn nodes for constructing boolean query on
828 * terms. First node points to processing info.
829 * Remaining nodes contain symbols for AND,
830 * OR, LEFT PARENTHESIS, RIGHT PARENTHESIS, or a SPECIAL or TOTAL term
831 * specification. The term specification nodes point to a CdTerm or a
832 * string.
833 *
834 *****************************************************************************/
835
EntrezTLNew(DocType type)836 NLM_EXTERN ValNodePtr LIBCALL EntrezTLNew (DocType type)
837
838 {
839 if (! DoSelectDataSourceByType(type, "BOOLEANS", NULL))
840 {
841 return NULL;
842 }
843
844 switch ( lastBooleanMediaType = GetCurMediaType() ) {
845 #ifdef _CDENTREZ_
846 case MEDIUM_CD:
847 case MEDIUM_DISK:
848 #ifdef _MBENTREZ_
849 if (type == TYP_ML)
850 return MBEntTLNew(type);
851 #endif
852 #ifdef _PMENTREZ_
853 return PMEntTLNew(type);
854 #else
855 return CdEntTLNew(type);
856 #endif /* _PMENTREZ_ */
857 #endif
858 #ifdef _NETENTREZ_
859 case MEDIUM_NETWORK:
860 return NetEntTLNew(type);
861 #endif
862 default:
863 return NULL;
864 }
865 }
866
867 /*****************************************************************************
868 *
869 * EntrezTLAddTerm (elst, term, type, field, special)
870 * Adds a term node to a boolean algebraic term query.
871 *
872 *****************************************************************************/
873
EntrezTLAddTerm(ValNodePtr elst,CharPtr term,DocType type,DocField field,Boolean special)874 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddTerm (ValNodePtr elst, CharPtr term, DocType type, DocField field, Boolean special)
875 {
876 return EntrezTLAddTermWithRange (elst, term, type, field, special, NULL);
877 }
878
EntrezTLAddTermWithRange(ValNodePtr elst,CharPtr term,DocType type,DocField field,Boolean special,CharPtr highRange)879 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddTermWithRange (ValNodePtr elst, CharPtr term, DocType type, DocField field, Boolean special, CharPtr highRange)
880
881 {
882 switch (lastBooleanMediaType) {
883 #ifdef _CDENTREZ_
884 case MEDIUM_CD:
885 case MEDIUM_DISK:
886 #ifdef _MBENTREZ_
887 if (type == TYP_ML)
888 return MBEntTLAddTerm (elst, term, type, field, special, highRange);
889 #endif
890
891 #ifdef _PMENTREZ_
892 return PMEntTLAddTerm (elst, term, type, field, special, highRange);
893 #else
894 return CdEntTLAddTerm (elst, term, type, field, special, highRange);
895 #endif /* _PMENTREZ_ */
896
897 #endif
898 #ifdef _NETENTREZ_
899 case MEDIUM_NETWORK:
900 return NetEntTLAddTerm (elst, term, type, field, special, highRange);
901 #endif
902 default:
903 return NULL;
904 }
905 }
906
907 /*****************************************************************************
908 *
909 * EntrezTLFree (elst)
910 * Frees a boolean algebraic term query list.
911 *
912 *****************************************************************************/
913
EntrezTLFree(ValNodePtr elst)914 NLM_EXTERN ValNodePtr LIBCALL EntrezTLFree (ValNodePtr elst)
915
916 {
917 #ifdef _PMENTREZ_
918 return PMEntTLFree(elst);
919 #else
920
921 switch (lastBooleanMediaType) {
922 #ifdef _CDENTREZ_
923 case MEDIUM_CD:
924 case MEDIUM_DISK:
925 #ifdef _MBENTREZ_
926 {
927 if (elst != NULL && elst->choice == NULLSYM)
928 {
929 CdTermPtr eset = (CdTermPtr) elst->data.ptrvalue;
930
931 if (eset != NULL && eset->type == TYP_ML)
932 {
933 return MBEntTLFree(elst);
934 }
935 }
936 }
937 #endif
938 return CdEntTLFree(elst);
939 #endif
940
941 #ifdef _NETENTREZ_
942 case MEDIUM_NETWORK:
943 return NetEntTLFree(elst);
944 #endif
945 default:
946 return NULL;
947
948 }
949
950 #endif
951
952 }
953
954 /*****************************************************************************
955 *
956 * EntrezTLAddLParen (elst)
957 * Adds a LEFT PAREN node to a boolean algebraic term query.
958 *
959 *****************************************************************************/
960
EntrezTLAddLParen(ValNodePtr elst)961 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddLParen (ValNodePtr elst)
962
963 {
964 ValNodePtr anp;
965
966 anp = NULL;
967 if (elst != NULL) {
968 anp = ValNodeNew (elst);
969 if (anp != NULL) {
970 anp->choice = LPAREN;
971 }
972 }
973 return anp;
974 }
975
976 /*****************************************************************************
977 *
978 * EntrezTLAddRParen (elst)
979 * Adds a RIGHT PAREN node to a boolean algebraic term query.
980 *
981 *****************************************************************************/
982
EntrezTLAddRParen(ValNodePtr elst)983 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddRParen (ValNodePtr elst)
984
985 {
986 ValNodePtr anp;
987
988 anp = NULL;
989 if (elst != NULL) {
990 anp = ValNodeNew (elst);
991 if (anp != NULL) {
992 anp->choice = RPAREN;
993 }
994 }
995 return anp;
996 }
997
998 /*****************************************************************************
999 *
1000 * CdEntTLAddAND (elst)
1001 * Adds an AND node to a boolean algebraic term query.
1002 *
1003 *****************************************************************************/
1004
EntrezTLAddAND(ValNodePtr elst)1005 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddAND (ValNodePtr elst)
1006
1007 {
1008 ValNodePtr anp;
1009
1010 anp = NULL;
1011 if (elst != NULL) {
1012 anp = ValNodeNew (elst);
1013 if (anp != NULL) {
1014 anp->choice = ANDSYMBL;
1015 }
1016 }
1017 return anp;
1018 }
1019
1020 /*****************************************************************************
1021 *
1022 * EntrezTLAddOR (elst)
1023 * Adds an OR node to a boolean algebraic term query.
1024 *
1025 *****************************************************************************/
1026
EntrezTLAddOR(ValNodePtr elst)1027 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddOR (ValNodePtr elst)
1028
1029 {
1030 ValNodePtr anp;
1031
1032 anp = NULL;
1033 if (elst != NULL) {
1034 anp = ValNodeNew (elst);
1035 if (anp != NULL) {
1036 anp->choice = ORSYMBL;
1037 }
1038 }
1039 return anp;
1040 }
1041
1042 /*****************************************************************************
1043 *
1044 * EntrezTLAddBUTNOT (elst)
1045 * Adds an BUTNOT node to a boolean algebraic term query.
1046 *
1047 *****************************************************************************/
1048
EntrezTLAddBUTNOT(ValNodePtr elst)1049 NLM_EXTERN ValNodePtr LIBCALL EntrezTLAddBUTNOT (ValNodePtr elst)
1050
1051 {
1052 ValNodePtr anp;
1053
1054 anp = NULL;
1055 if (elst != NULL) {
1056 anp = ValNodeNew (elst);
1057 if (anp != NULL) {
1058 anp->choice = BUTNOTSYMBL;
1059 }
1060 }
1061 return anp;
1062 }
1063
1064 /*****************************************************************************
1065 *
1066 * EntrezTLEval (elst)
1067 * Evaluates a boolean algebraic term query list, returning a pointer to
1068 * a LinkSet containing the resultant unique identifiers.
1069 *
1070 *****************************************************************************/
1071
1072
EntrezPMTLEval(ValNodePtr elst,void * edc)1073 NLM_EXTERN LinkSetPtr LIBCALL EntrezPMTLEval (ValNodePtr elst, void * edc)
1074 {
1075
1076 switch (lastBooleanMediaType) {
1077 #ifdef _CDENTREZ_
1078 case MEDIUM_CD:
1079 case MEDIUM_DISK:
1080 #if defined(_MBENTREZ_) || defined(_PMENTREZ_)
1081 {
1082 if (elst != NULL && elst->choice == NULLSYM)
1083 {
1084 CdTermPtr eset = (CdTermPtr) elst->data.ptrvalue;
1085 #ifdef _MBENTREZ_
1086 if (eset != NULL && eset->type == TYP_ML)
1087 {
1088 return MBEntTLEval(elst);
1089 #else
1090 if (eset != NULL && DatabaseExistsInPubMed(eset->type))
1091 {
1092 return PMEntTLEval(eset -> type,elst,edc);
1093 #endif
1094 }
1095 }
1096 }
1097 #endif
1098 return CdEntTLEval(elst);
1099 #endif
1100 #ifdef _NETENTREZ_
1101 case MEDIUM_NETWORK:
1102 return NetEntTLEval(elst);
1103 #endif
1104 default:
1105 return NULL;
1106 }
1107 }
1108
1109 NLM_EXTERN LinkSetPtr LIBCALL EntrezTLEval (ValNodePtr elst)
1110 {
1111 return EntrezPMTLEval (elst,NULL);
1112 }
1113
1114 /*****************************************************************************
1115 *
1116 * EntrezTLEvalCount (elst)
1117 * Evaluates a boolean algebraic term query list, returning the count
1118 * of resulting UIDs.
1119 *****************************************************************************/
1120
1121 NLM_EXTERN Int4 LIBCALL EntrezPMTLEvalCount (ValNodePtr elst, void * edc)
1122 {
1123 Int4 retval;
1124
1125 switch (lastBooleanMediaType) {
1126 #ifdef _CDENTREZ_
1127 case MEDIUM_CD:
1128 case MEDIUM_DISK:
1129 #if defined(_MBENTREZ_) || defined(_PMENTREZ_)
1130 {
1131 if (elst != NULL && elst->choice == NULLSYM)
1132 {
1133 CdTermPtr eset = (CdTermPtr) elst->data.ptrvalue;
1134
1135 #ifdef _MBENTREZ_
1136 if (eset != NULL && eset->type == TYP_ML)
1137 {
1138 return MBEntTLEvalCount(elst);
1139 #else
1140 if (eset != NULL && DatabaseExistsInPubMed(eset->type))
1141 {
1142 return PMEntTLEvalCount(eset -> type, elst,edc);
1143 #endif
1144 }
1145 }
1146 }
1147 #endif
1148 retval = CdEntTLEvalCount(elst);
1149 return retval;
1150 #endif
1151 #ifdef _NETENTREZ_
1152 case MEDIUM_NETWORK:
1153 retval = NetEntTLEvalCount(elst);
1154 return retval;
1155 #endif
1156 default:
1157 return 0;
1158 }
1159 }
1160
1161 NLM_EXTERN Int4 LIBCALL EntrezTLEvalCount (ValNodePtr elst)
1162 {
1163 return EntrezPMTLEvalCount (elst, NULL);
1164 }
1165
1166
1167 /*****************************************************************************
1168 *
1169 * EntrezTLEvalX (elst)
1170 * Evaluates a boolean algebraic term query list, returning a pointer to
1171 * a ByteStore containing the resultant unique identifiers. The number
1172 * of UIDs is calculated as BSLen (bsp) / sizeof (DocUid).
1173 *
1174 *****************************************************************************/
1175
1176 NLM_EXTERN ByteStorePtr LIBCALL EntrezPMTLEvalX (ValNodePtr elst, void * edc)
1177 {
1178 ByteStorePtr bsp;
1179
1180 switch (lastBooleanMediaType) {
1181 #ifdef _CDENTREZ_
1182 case MEDIUM_CD:
1183 case MEDIUM_DISK:
1184 #if defined(_MBENTREZ_) || defined(_PMENTREZ_)
1185 {
1186 if (elst != NULL && elst->choice == NULLSYM)
1187 {
1188 CdTermPtr eset = (CdTermPtr) elst->data.ptrvalue;
1189 #ifdef _MBENTREZ_
1190 if (eset != NULL && eset->type == TYP_ML)
1191 {
1192 bsp = MBEntTLEvalX(elst);
1193 #else
1194 if (eset != NULL && DatabaseExistsInPubMed(eset->type))
1195 {
1196 bsp = PMEntTLEvalX(eset -> type, elst,edc);
1197 #endif
1198 if (bsp != NULL) {
1199 BSSeek (bsp, 0L, 0);
1200 }
1201 return bsp;
1202 }
1203 }
1204 }
1205 #endif
1206 bsp = CdEntTLEvalX(elst);
1207 if (bsp != NULL) {
1208 BSSeek (bsp, 0L, 0);
1209 }
1210 return bsp;
1211 #endif
1212 #ifdef _NETENTREZ_
1213 case MEDIUM_NETWORK:
1214 bsp = NetEntTLEvalX(elst);
1215 if (bsp != NULL) {
1216 BSSeek (bsp, 0L, 0);
1217 }
1218 return bsp;
1219 #endif
1220 default:
1221 return NULL;
1222 }
1223 }
1224
1225 NLM_EXTERN ByteStorePtr LIBCALL EntrezTLEvalX (ValNodePtr elst)
1226 {
1227 return(EntrezPMTLEvalX(elst,NULL));
1228 }
1229
1230
1231 #ifdef USE_IDxARCH
1232 static Boolean
1233 ConnectID(void)
1234 {
1235 if (!idConnected && !idCantConnect)
1236 {
1237 if (IDxArchInit())
1238 {
1239 idConnected = TRUE;
1240 } else {
1241 idCantConnect = TRUE;
1242 }
1243 }
1244
1245 return idConnected;
1246 }
1247
1248 static void
1249 DisconnID(void)
1250 {
1251 if (idConnected)
1252 IDxArchFini();
1253 idConnected = FALSE;
1254 idCantConnect = FALSE;
1255 }
1256 #endif /* USE_IDxARCH */
1257
1258 /*****************************************************************************
1259 *
1260 * DocSumPtr EntrezDocSum(type, uid)
1261 *
1262 *****************************************************************************/
1263 NLM_EXTERN DocSumPtr LIBCALL EntrezDocSum (DocType type, DocUid uid)
1264
1265 {
1266 DocSumPtr dsp;
1267
1268 #ifdef _PMENTREZ_
1269 return PMDocSum(type, uid);
1270 #else
1271
1272 if (! DoSelectDataSourceByType(type, "DOCSUMS", NULL))
1273 { /* ERROR, data unobtainable */
1274 return NULL;
1275 }
1276
1277 do {
1278 switch (GetCurMediaType())
1279 {
1280 #ifdef _CDENTREZ_
1281 case MEDIUM_CD:
1282 case MEDIUM_DISK:
1283 #ifdef _MBENTREZ_
1284 if (type == TYP_ML)
1285 {
1286 return MBDocSum(type, uid);
1287 }
1288 #endif
1289 if ((dsp = CdDocSum (type, uid)) != NULL)
1290 return dsp;
1291 #ifdef USE_IDxARCH
1292 if (type != TYP_ST && type != TYP_CH && ConnectID())
1293 {
1294 SeqEntryPtr sep;
1295 Char fname[PATH_MAX];
1296 AsnIoPtr aip;
1297 DocSumPtr dsp = NULL;
1298
1299 if ((sep = IDxArchSeqEntryGet(uid, NULL, 0)) != NULL)
1300 {
1301 TmpNam(fname);
1302 aip = AsnIoOpen(fname, "w");
1303 SeqEntryAsnWrite(sep, aip, NULL);
1304 AsnIoClose(aip);
1305 aip = AsnIoOpen(fname, "r");
1306 dsp = CdSeqSumAsnRead(aip, uid);
1307 SeqEntryFree(sep);
1308 AsnIoClose(aip);
1309 FileRemove(fname);
1310 return dsp;
1311 }
1312 }
1313 #endif /* USE_IDxARCH */
1314 break;
1315 #endif
1316 #ifdef _NETENTREZ_
1317 case MEDIUM_NETWORK:
1318 if ((dsp = NetDocSum (type, uid)) != NULL)
1319 return dsp;
1320 break;
1321 #endif
1322 default:
1323 break;
1324 }
1325 } while (SelectNextDataSource());
1326
1327 return NULL;
1328
1329 #endif
1330 }
1331
1332 /*****************************************************************************
1333 *
1334 * EntrezDocSumListGet(numuid, type, uids, callback)
1335 *
1336 *****************************************************************************/
1337 static Int2 DocSumQueueGet (Int2 numuid, DocType type, DocSumListCallBack callback)
1338
1339 {
1340 DocSumPtr dsp;
1341 int count = 0;
1342 int i;
1343 Boolean goOn;
1344
1345 if (callback == NULL) {
1346 ClearQueuedDocSums ();
1347 return 0;
1348 }
1349 if (type != queuedtype) {
1350 ClearQueuedDocSums ();
1351 return 0;
1352 }
1353 goOn = TRUE;
1354 count = 0;
1355 if (numuid > numqueued) {
1356 numuid = numqueued;
1357 }
1358
1359 i = 0;
1360 while (i < numqueued && goOn) {
1361 if (queueduids [i] != 0) {
1362 if (queuedsums != NULL) {
1363 dsp = queuedsums [i];
1364 } else {
1365 dsp = EntrezDocSum (type, queueduids [i]);
1366 }
1367 if (dsp != NULL) {
1368 count++;
1369 goOn = callback (dsp, dsp->uid);
1370 queueduids [i] = 0;
1371 if (queuedsums != NULL) {
1372 queuedsums [i] = NULL;
1373 }
1374 } else {
1375 count++;
1376 goOn = callback (NULL, queueduids [i]);
1377 queueduids [i] = 0;
1378 if (queuedsums != NULL) {
1379 queuedsums [i] = NULL;
1380 }
1381 }
1382 }
1383 i++;
1384 }
1385 if (i >= numqueued) {
1386 if (queuedsums != NULL) {
1387 queuedsums = (DocSumPtr PNTR) MemFree (queuedsums);
1388 }
1389 queueduids = (DocUidPtr) MemFree (queueduids);
1390 numqueued = 0;
1391 }
1392
1393 return count;
1394 }
1395
1396 NLM_EXTERN Int2 LIBCALL EntrezDocSumListGet (Int2 numuid, DocType type, DocUidPtr uids,
1397 DocSumListCallBack callback)
1398
1399 {
1400 DocSumPtr dsp;
1401 int count = 0;
1402 int i;
1403 Boolean goOn;
1404 DocUidPtr uidlist;
1405 #ifdef _NETENTREZ_
1406 Int2 chunkSize;
1407 Int2 chunkStart;
1408 Int2 predictedNextChunk;
1409 Int2 actual;
1410 DocSumPtr PNTR result;
1411 static Int2 adaptiveChunkSize = ADAPTIVE_MATRIX_INITIAL_CONDITION;
1412 time_t timeElapsed, startTime;
1413 #endif
1414
1415 /* For ergonomics, DocSums are fetched from the CD-ROM and displayed */
1416 /* one at a time. For efficiency, all DocSums are fetched from the */
1417 /* network at once, and subsequently all are displayed. */
1418
1419 if (uids == NULL && queueduids != NULL && callback != NULL) {
1420 return DocSumQueueGet (numuid, queuedtype, callback);
1421 }
1422 ClearQueuedDocSums ();
1423 queuedtype = type;
1424 if (numuid == 0) {
1425 return 0;
1426 }
1427 if (uids == NULL) {
1428 return 0;
1429 }
1430 goOn = TRUE;
1431 count = 0;
1432 uidlist = (DocUidPtr) MemNew (sizeof (DocUid) * numuid);
1433 if (uidlist != NULL) {
1434 for (i = 0; i < numuid; i++) {
1435 uidlist [i] = uids [i];
1436 }
1437 #ifdef _NETENTREZ_
1438
1439 if (! DoSelectDataSourceByType(type, "DOCSUMS", NULL))
1440 { /* ERROR, data unobtainable */
1441 uidlist = (DocUidPtr) MemFree(uidlist);
1442 return 0;
1443 }
1444
1445 /* if the first-found media type is NET, try to get them all from the */
1446 /* net; otherwise, to heck with it, just get them one at a time, below */
1447 if (GetCurMediaType() == MEDIUM_NETWORK) {
1448 result = (DocSumPtr PNTR) MemNew (sizeof (DocSumPtr) * numuid);
1449 if (result != NULL) {
1450 i = 0;
1451 chunkStart = 0;
1452 chunkSize = adaptiveChunkSize;
1453 while (chunkStart < numuid && goOn)
1454 {
1455 /* if ( the callback told us that it doesn't need any more right */
1456 /* now, OR if we would be getting too many ) THEN */
1457 /* get all of the remaining docsums in one shot */
1458 if (callback == NULL || !goOn || (chunkSize + chunkStart) >= numuid)
1459 chunkSize = numuid - chunkStart;
1460
1461 /* Ask for some to be computed in advance, because it can take the*/
1462 /* application a long time to process the ones which it _does_ */
1463 /* receive this time */
1464 predictedNextChunk = MIN(numuid - (chunkStart+chunkSize), chunkSize);
1465 startTime = GetSecs();
1466 actual = NetDocSumListGet (&result[chunkStart], (Int2)(chunkSize +
1467 predictedNextChunk), type,
1468 &uids[chunkStart], predictedNextChunk);
1469 chunkStart += chunkSize;
1470
1471 timeElapsed = GetSecs() - startTime;
1472 if (timeElapsed < 0)
1473 timeElapsed = 0;
1474 if (timeElapsed > MAX_SECS_IN_ADAPTIVE_MATRIX)
1475 timeElapsed = MAX_SECS_IN_ADAPTIVE_MATRIX;
1476 if (chunkSize > MAX_CHUNK_IN_ADAPTIVE_MATRIX)
1477 chunkSize = MAX_CHUNK_IN_ADAPTIVE_MATRIX;
1478 adaptiveChunkSize = AdaptiveDocSumMatrix[chunkSize][timeElapsed];
1479 chunkSize = adaptiveChunkSize;
1480
1481 if (goOn && callback != NULL) {
1482 while (i < chunkStart && goOn) {
1483 dsp = result [i];
1484 if (dsp != NULL) {
1485 count++;
1486 goOn = callback (dsp, dsp->uid);
1487 uidlist [i] = 0;
1488 result [i] = NULL;
1489 } else {
1490 count++;
1491 goOn = callback (NULL, uidlist [i]);
1492 uidlist [i] = 0;
1493 result [i] = NULL;
1494 }
1495 i++;
1496 }
1497 }
1498 }
1499
1500 if (count < numuid) { /* enqueue remaining docsums */
1501 queueduids = uidlist;
1502 queuedsums = result;
1503 numqueued = numuid;
1504 } else {
1505 MemFree (uidlist);
1506 MemFree (result);
1507 }
1508 }
1509 return count;
1510 }
1511 #endif
1512
1513 /* get them one at a time */
1514 if (callback != NULL) {
1515 i = 0;
1516 while (i < numuid && goOn) {
1517 dsp = EntrezDocSum (type, uidlist [i]);
1518 if (dsp != NULL) {
1519 count++;
1520 goOn = callback (dsp, dsp->uid);
1521 uidlist [i] = 0;
1522 } else {
1523 count++;
1524 goOn = callback (NULL, uidlist [i]);
1525 uidlist [i] = 0;
1526 }
1527 i++;
1528 }
1529 }
1530 if (count < numuid) {
1531 queueduids = uidlist;
1532 numqueued = numuid;
1533 } else {
1534 MemFree (uidlist);
1535 }
1536 }
1537 return count;
1538 }
1539
1540
1541 /*****************************************************************************
1542 *
1543 * EntrezTermListByTerm (type, field, term, numterms, proc, first_page)
1544 * Gets Terms starting at term
1545 * returns pages read
1546 * sets first_page to first page read
1547 *
1548 *****************************************************************************/
1549 NLM_EXTERN Int2 LIBCALL EntrezTermListByTerm (DocType type, DocField field, CharPtr term, Int2 numterms, TermListProc proc, Int2Ptr first_page)
1550
1551 {
1552 if (! DoSelectDataSourceByType(type, "TERMS", NULL))
1553 {
1554 return 0;
1555 }
1556
1557
1558 lastTermType = type;
1559
1560 switch (GetCurMediaType())
1561 {
1562 #ifdef _CDENTREZ_
1563 case MEDIUM_CD:
1564 case MEDIUM_DISK:
1565 #ifdef _MBENTREZ_
1566 if (type == TYP_ML && field != FLD_PROT /* FLD_PROT is MeSH glossary */)
1567 {
1568 return MBTermListByTerm(type, field, term, numterms, proc, first_page);
1569 }
1570 #endif
1571 #ifdef _PMENTREZ_
1572 if (DatabaseExistsInPubMed(type))
1573 {
1574 return PMTermListByTerm(type, field, term, numterms, proc, first_page);
1575 }
1576 #endif
1577 return CdTermListByTerm(type, field, term, numterms, proc, first_page);
1578 #endif
1579 #ifdef _NETENTREZ_
1580 case MEDIUM_NETWORK:
1581 return NetTermListByTerm(type, field, term, numterms, proc, first_page);
1582 #endif
1583 default:
1584 return 0;
1585 }
1586 }
1587
1588 /*****************************************************************************
1589 *
1590 * EntrezTermListByPage (type, field, page, numpage, proc)
1591 * Gets terms starting at page, for numpage, by calling proc
1592 * returns pages read
1593 *
1594 *****************************************************************************/
1595 NLM_EXTERN Int2 LIBCALL EntrezTermListByPage (DocType type, DocField field, Int2 page, Int2 numpage, TermListProc proc)
1596
1597 {
1598 if (! DoSelectDataSourceByType(type, "TERMS", NULL))
1599 {
1600 return 0;
1601 }
1602
1603 lastTermType = type;
1604
1605 switch (GetCurMediaType())
1606 {
1607 #ifdef _CDENTREZ_
1608 case MEDIUM_CD:
1609 case MEDIUM_DISK:
1610 #ifdef _MBENTREZ_
1611 if (type == TYP_ML && field != FLD_PROT /* FLD_PROT is MeSH glossary */)
1612 {
1613 return MBTermListByPage(type, field, page, numpage, proc);
1614 }
1615 #endif
1616 #ifdef _PMENTREZ_
1617 if (DatabaseExistsInPubMed(type))
1618 {
1619 return PMTermListByPage(type, field, page, numpage, proc);
1620 }
1621 #endif
1622 return CdTermListByPage(type, field, page, numpage, proc);
1623 #endif
1624 #ifdef _NETENTREZ_
1625 case MEDIUM_NETWORK:
1626 return NetTermListByPage(type, field, page, numpage, proc);
1627 #endif
1628 default:
1629 return 0;
1630 }
1631 }
1632
1633 /*****************************************************************************
1634 *
1635 * EntrezFindTerm(type, field, term, spec, total)
1636 * returns count of special and total for a term
1637 * if term ends with "...", does a truncated merge of the term
1638 *
1639 *****************************************************************************/
1640 NLM_EXTERN Boolean LIBCALL EntrezFindTerm (DocType type, DocField field, CharPtr term, Int4Ptr spcl, Int4Ptr totl)
1641
1642 {
1643 if (! DoSelectDataSourceByType(type, "TERMS", NULL))
1644 {
1645 return 0;
1646 }
1647
1648 switch (GetCurMediaType())
1649 {
1650 #ifdef _CDENTREZ_
1651 case MEDIUM_CD:
1652 case MEDIUM_DISK:
1653 #ifdef _MBENTREZ_
1654 if (type == TYP_ML && field != FLD_PROT /* FLD_PROT is MeSH glossary */)
1655 {
1656 return MBEntrezFindTerm (type, field, term, spcl, totl);
1657 }
1658 #endif
1659 #ifdef _PMENTREZ_
1660 if (DatabaseExistsInPubMed(type))
1661 {
1662 return PMEntrezFindTerm (type, field, term, spcl, totl);
1663 }
1664 #endif
1665 return CdEntrezFindTerm (type, field, term, spcl, totl);
1666 #endif
1667 #ifdef _NETENTREZ_
1668 case MEDIUM_NETWORK:
1669 return NetEntrezFindTerm (type, field, term, spcl, totl);
1670 #endif
1671 default:
1672 return 0;
1673 }
1674 }
1675
1676
1677 /*****************************************************************************
1678 *
1679 * EntrezUidLinks()
1680 * retrieves links to other uids
1681 *
1682 *****************************************************************************/
1683 NLM_EXTERN LinkSetPtr LIBCALL EntrezUidLinks (DocType type, DocUid uid, DocType link_to_type)
1684
1685 {
1686 LinkSetPtr lsp;
1687
1688 if (! SelectDataLinksByTypes(type, link_to_type))
1689 {
1690 return NULL;
1691 }
1692
1693 do {
1694 switch (GetCurMediaType())
1695 {
1696 #ifdef _CDENTREZ_
1697 case MEDIUM_CD:
1698 case MEDIUM_DISK:
1699 #ifdef _MBENTREZ_
1700 if (type == TYP_ML && link_to_type == TYP_ML)
1701 {
1702 return MBUidLinks(type, uid, link_to_type);
1703 }
1704 #endif
1705 #ifdef _PMENTREZ_
1706 return PMUidLinks(type, uid, link_to_type);
1707 #else
1708 if ((lsp = CdUidLinks(type, uid, link_to_type)) != NULL)
1709 return lsp;
1710 break;
1711 #endif /* _PMENTREZ_ */
1712
1713 #endif
1714 #ifdef _NETENTREZ_
1715 case MEDIUM_NETWORK:
1716 if ((lsp = NetUidLinks(type, uid, link_to_type)) != NULL)
1717 return lsp;
1718 break;
1719 #endif
1720 default:
1721 break;
1722 }
1723 } while (SelectNextDataSource());
1724
1725 return NULL;
1726 }
1727
1728
1729 /*****************************************************************************
1730 *
1731 * EntrezLinkUidList(type, link_to_type, numuid, uids)
1732 * returns count of input uids processed
1733 * returns -1 on error
1734 * if neighbors (type == link_to_type)
1735 * sums weights for same uids
1736 * if (more than EntrezUserMaxLinks() uids, frees uids and weights,
1737 * but leaves num set)
1738 *
1739 *****************************************************************************/
1740 NLM_EXTERN Int2 LIBCALL EntrezLinkUidList (LinkSetPtr PNTR result, DocType type, DocType link_to_type, Int2 numuid, Int4Ptr uids, Boolean mark_missing)
1741
1742 {
1743 Int2 obtained_ids = 0;
1744 Int4Ptr local_uids;
1745 Int4Ptr best_obtained_uids;
1746 Int2 best_obtained_ids = 0;
1747 LinkSetPtr best_lsp = NULL;
1748 LinkSetPtr lsp;
1749 Int2 i;
1750 Int2 missing = 0;
1751 Int2 fewest_missing = numuid + 1;
1752 Boolean badErr = FALSE;
1753
1754 if (numuid == 0)
1755 return 0;
1756
1757 if (! SelectDataLinksByTypes(type, link_to_type))
1758 { /* ERROR, data unobtainable */
1759 return 0;
1760 }
1761
1762 local_uids = (Int4Ptr) MemNew(numuid * sizeof(Int4));
1763 best_obtained_uids = (Int4Ptr) MemNew(numuid * sizeof(Int4));
1764
1765 /* Try the various available data sources, and return "successfully" if */
1766 /* a data source is located with neighbors for all requested UIDs. */
1767 /* If no such data source can be located, then try all data sources, */
1768 /* selecting the one for which the most possible UIDs have neighbors. */
1769 /* When two or more UIDs have the same number of UIDs with neighbors, use */
1770 /* the number of obtained neighbors as a tie-breaker. */
1771
1772 do {
1773 MemCopy (local_uids, uids, numuid * sizeof(*uids));
1774
1775 switch (GetCurMediaType())
1776 {
1777 #ifdef _CDENTREZ_
1778 case MEDIUM_CD:
1779 case MEDIUM_DISK:
1780 #ifdef _MBENTREZ_
1781 if (type == TYP_ML && link_to_type == TYP_ML)
1782 {
1783 obtained_ids = MBLinkUidList(&lsp, type, link_to_type, numuid,
1784 local_uids, TRUE);
1785 break;
1786 }
1787 #endif
1788 #ifdef _PMENTREZ_
1789 obtained_ids = PMLinkUidList(&lsp, type, link_to_type, numuid,
1790 local_uids, TRUE);
1791 break;
1792
1793 #else
1794 obtained_ids = CdLinkUidList(&lsp, type, link_to_type, numuid,
1795 local_uids, TRUE);
1796 break;
1797
1798 #endif /* _PMENTREZ_ */
1799 #endif
1800 #ifdef _NETENTREZ_
1801 case MEDIUM_NETWORK:
1802 obtained_ids = NetLinkUidList(&lsp, type, link_to_type, numuid,
1803 local_uids, TRUE);
1804 break;
1805 #endif
1806 default:
1807 badErr = TRUE;
1808 break;
1809 }
1810
1811 if (badErr)
1812 break;
1813
1814 for (missing = 0, i = 0; i < numuid; i++)
1815 {
1816 if (local_uids[i] < 0)
1817 missing++;
1818 }
1819
1820 if (missing == 0) /* success */
1821 {
1822 break;
1823 }
1824
1825 if (missing <= fewest_missing)
1826 {
1827 if (missing < fewest_missing || best_lsp == NULL ||
1828 lsp->num > best_lsp->num)
1829 { /* found a better match */
1830 if (best_lsp != NULL)
1831 LinkSetFree(best_lsp);
1832 best_lsp = lsp;
1833 fewest_missing = missing;
1834 best_obtained_ids = obtained_ids;
1835 MemCopy(best_obtained_uids, local_uids, numuid * sizeof(*uids));
1836 }
1837 }
1838 else {
1839 LinkSetFree(lsp);
1840 }
1841 } while (SelectNextDataSource()); /* until we've run out of options */
1842
1843 if (missing == 0)
1844 { /* found neighbors for all UIDs */
1845 if (best_lsp != NULL)
1846 LinkSetFree(best_lsp);
1847 *result = lsp;
1848 if (mark_missing)
1849 MemCopy(uids, local_uids, numuid * sizeof(*uids));
1850 MemFree(local_uids);
1851 MemFree(best_obtained_uids);
1852 return obtained_ids;
1853 }
1854 else { /* couldn't find links for all; return best */
1855 *result = best_lsp;
1856 if (mark_missing)
1857 MemCopy(uids, best_obtained_uids, numuid * sizeof(*uids));
1858 MemFree(local_uids);
1859 MemFree(best_obtained_uids);
1860 return best_obtained_ids;
1861 }
1862 }
1863
1864 /*****************************************************************************
1865 *
1866 * EntrezMedlineEntryListGet (result, numuid, uids, mark_missing)
1867 * returns a count of entries read
1868 * if (mark_missing) ids which could not be located are made negative
1869 *
1870 *****************************************************************************/
1871 NLM_EXTERN Int2 LIBCALL EntrezMedlineEntryListGet(MedlineEntryPtr PNTR result, Int2 numuid,
1872 Int4Ptr uids, Boolean mark_missing)
1873 {
1874 Int2 obtained_ids = 0;
1875 Int4Ptr local_uids;
1876 int unmatched;
1877 Int4Ptr map;
1878 Boolean first_time;
1879 MedlineEntryPtr PNTR res;
1880 Int2 i;
1881
1882 if (numuid == 0)
1883 return 0;
1884
1885 #ifdef _PMENTREZ_
1886 return PMEntMedlineEntryListGet (result, numuid, uids);
1887 #else
1888
1889 first_time = TRUE;
1890
1891 if (! DoSelectDataSource(ENTR_REF_CHAN, "RECORDS", NULL)) /* MEDLINE DATA (Abstracts) */
1892 {
1893 /* ERROR, data unobtainable */
1894 return 0;
1895 }
1896
1897 local_uids = (Int4Ptr) MemDup(uids, numuid * sizeof(*uids));
1898 res = (MedlineEntryPtr PNTR) MemNew(numuid * sizeof(MedlineEntryPtr));
1899 map = (Int4Ptr) MemNew(numuid * sizeof(Int4));
1900
1901 do {
1902 switch (GetCurMediaType())
1903 {
1904 #ifdef _CDENTREZ_
1905 case MEDIUM_CD:
1906 case MEDIUM_DISK:
1907 #ifdef _MBENTREZ_
1908 obtained_ids += MBEntMedlineEntryListGet (res, numuid, local_uids, TRUE);
1909 break;
1910 #endif
1911 obtained_ids += CdEntMedlineEntryListGet (res, numuid, local_uids, TRUE);
1912 break;
1913 #endif
1914 #ifdef _NETENTREZ_
1915 case MEDIUM_NETWORK:
1916 obtained_ids += NetEntMedlineEntryListGet (res, numuid, local_uids, TRUE);
1917 break;
1918 #endif
1919 default:
1920 break;
1921 }
1922
1923 for (unmatched = 0, i = 0; i < numuid; i++)
1924 {
1925 if (local_uids[i] >= 0) /* found this one */
1926 {
1927 if (first_time)
1928 {
1929 result[i] = res[i];
1930 }
1931 else
1932 { /* map the location */
1933 result[map[i]] = res[i];
1934 }
1935 }
1936 else {
1937 if (first_time)
1938 {
1939 result[i] = NULL;
1940 if (mark_missing)
1941 uids[i] = local_uids[i];
1942 map[unmatched] = i;
1943 }
1944 else {
1945 map[unmatched] = map[i];
1946 }
1947 local_uids[unmatched] = ABS(local_uids[i]);
1948 unmatched++;
1949 }
1950 }
1951
1952 numuid = unmatched;
1953 first_time = FALSE;
1954
1955 } while (numuid > 0 && SelectNextDataSource()); /* until we've run out of options */
1956
1957 MemFree (local_uids);
1958 MemFree (res);
1959 MemFree (map);
1960
1961 return obtained_ids;
1962 #endif
1963 }
1964
1965 /*****************************************************************************
1966 *
1967 * EntrezMedlineEntryGet(uid)
1968 * get one MedlineEntry
1969 *
1970 *****************************************************************************/
1971 NLM_EXTERN MedlineEntryPtr LIBCALL EntrezMedlineEntryGet (Int4 uid)
1972
1973 {
1974 MedlineEntryPtr mep = NULL;
1975 ErrStrId errorID;
1976 char errorString[35];
1977
1978 sprintf(errorString, "(EntrezMedlineEntryGet: %ld)",(long)uid);
1979 errorID = Nlm_ErrUserInstall(errorString, 0);
1980
1981 EntrezMedlineEntryListGet(&mep, 1, &uid, FALSE);
1982 Nlm_ErrUserDelete(errorID);
1983
1984 return mep;
1985 }
1986
1987
1988 /*****************************************************************************
1989 *
1990 * EntrezPubmedEntryListGet (result, numuid, uids, mark_missing)
1991 * returns a count of entries read
1992 * if (mark_missing) ids which could not be located are made negative
1993 *
1994 *****************************************************************************/
1995 #ifdef _PMENTREZ_
1996
1997 Int2 LIBCALL EntrezPubmedEntryListGet(PubmedEntryPtr PNTR result, Int2 numuid,
1998 Int4Ptr uids, Boolean mark_missing)
1999 {
2000 Int2 obtained_ids = 0;
2001 Int4Ptr local_uids;
2002 int unmatched;
2003 Int4Ptr map;
2004 Boolean first_time;
2005 PubmedEntryPtr PNTR res;
2006 Int2 i;
2007
2008 if (numuid == 0)
2009 return 0;
2010
2011 first_time = TRUE;
2012
2013 if (! DoSelectDataSource(ENTR_REF_CHAN, "RECORDS", NULL))
2014 {
2015 /* ERROR, data unobtainable */
2016 return 0;
2017 }
2018
2019 local_uids = (Int4Ptr) MemDup(uids, numuid * sizeof(*uids));
2020 res = (PubmedEntryPtr PNTR) MemNew(numuid * sizeof(PubmedEntryPtr));
2021 map = (Int4Ptr) MemNew(numuid * sizeof(Int4));
2022
2023 do {
2024 switch (GetCurMediaType())
2025 {
2026 #ifdef _CDENTREZ_
2027 case MEDIUM_CD:
2028 case MEDIUM_DISK:
2029 #ifdef _PMENTREZ_
2030 obtained_ids += PubmedEntryListGet (res, numuid, local_uids, TRUE);
2031 break;
2032 #endif
2033 break;
2034 #endif
2035 #ifdef _NETENTREZ_
2036 case MEDIUM_NETWORK:
2037 obtained_ids += NetEntPubmedEntryListGet (res, numuid, local_uids, TRUE);
2038 break;
2039 #endif
2040 default:
2041 break;
2042 }
2043
2044 for (unmatched = 0, i = 0; i < numuid; i++)
2045 {
2046 if (local_uids[i] >= 0) /* found this one */
2047 {
2048 if (first_time)
2049 {
2050 result[i] = res[i];
2051 }
2052 else
2053 { /* map the location */
2054 result[map[i]] = res[i];
2055 }
2056 }
2057 else {
2058 if (first_time)
2059 {
2060 result[i] = NULL;
2061 if (mark_missing)
2062 uids[i] = local_uids[i];
2063 map[unmatched] = i;
2064 }
2065 else {
2066 map[unmatched] = map[i];
2067 }
2068 local_uids[unmatched] = ABS(local_uids[i]);
2069 unmatched++;
2070 }
2071 }
2072
2073 numuid = unmatched;
2074 first_time = FALSE;
2075
2076 } while (numuid > 0 && SelectNextDataSource()); /* until we've run out of options */
2077
2078 MemFree (local_uids);
2079 MemFree (res);
2080 MemFree (map);
2081
2082 return obtained_ids;
2083 }
2084
2085 /*****************************************************************************
2086 *
2087 * EntrezPubmedEntryGet(uid)
2088 * get one PubmedEntry
2089 *
2090 *****************************************************************************/
2091 PubmedEntryPtr LIBCALL EntrezPubmedEntryGet (Int4 uid)
2092
2093 {
2094 PubmedEntryPtr mep = NULL;
2095
2096 EntrezPubmedEntryListGet(&mep, 1, &uid, FALSE);
2097 return mep;
2098 }
2099
2100 #endif
2101
2102 /*****************************************************************************
2103 *
2104 * EntrezBiostrucGet(uid, Int4 mdlLvl, Int4 maxModels)
2105 * get one Biostruc
2106 *
2107 *****************************************************************************/
2108
2109 #ifdef Biostruc_supported
2110
2111 NLM_EXTERN BiostrucPtr LIBCALL EntrezBiostrucGet (DocUid uid, Int4 mdlLvl, Int4 maxModels)
2112 {
2113 BiostrucPtr retval = NULL;
2114
2115 #ifdef _PMENTREZ_
2116 return PMEntrezBiostrucGet(uid,mdlLvl,maxModels);
2117 #else
2118
2119 if (! DoSelectDataSource(ENTR_SEQ_CHAN, "RECORDS", NULL)) /* SEQUENCE DATA (Abstracts) */
2120 {
2121 /* ERROR, data unobtainable */
2122 return NULL;
2123 }
2124
2125 switch (GetCurMediaType())
2126 {
2127 #ifdef _CDENTREZ_
2128 case MEDIUM_CD:
2129 case MEDIUM_DISK:
2130 return CdEntrezBiostrucGet(uid, mdlLvl, maxModels);
2131 #endif
2132 #ifdef _NETENTREZ_
2133 case MEDIUM_NETWORK:
2134 NetEntrezBiostrucListGet(&retval, mdlLvl, maxModels, 1, &uid, FALSE);
2135 return retval;
2136 #endif
2137 default:
2138 return NULL;
2139 }
2140 #endif
2141 }
2142
2143 NLM_EXTERN BiostrucAnnotSetPtr LIBCALL EntrezBiostrucAnnotSetGet (DocUid uid)
2144 {
2145 if (! DoSelectDataSource(ENTR_SEQ_CHAN, "RECORDS", NULL)) /* SEQUENCE DATA (Abstracts) */
2146 {
2147 /* ERROR, data unobtainable */
2148 return NULL;
2149 }
2150
2151 switch (GetCurMediaType())
2152 {
2153 #ifdef _CDENTREZ_
2154 case MEDIUM_CD:
2155 case MEDIUM_DISK:
2156 return CdEntrezBiostrucAnnotSetGet(uid);
2157 #endif
2158 #ifdef _NETENTREZ_
2159 case MEDIUM_NETWORK:
2160 return NetEntrezBiostrucAnnotSetGet(uid);
2161 #endif
2162 default:
2163 return NULL;
2164 }
2165 }
2166
2167 NLM_EXTERN LinkSetPtr LIBCALL EntrezBiostrucFeatIds(DocUid mmdbid, Int2 feature_type, Int4 feature_set_id)
2168 {
2169 if (! DoSelectDataSource(ENTR_SEQ_CHAN, "RECORDS", NULL)) /* SEQUENCE DATA (Abstracts) */
2170 {
2171 /* ERROR, data unobtainable */
2172 return NULL;
2173 }
2174
2175 switch (GetCurMediaType())
2176 {
2177 #ifdef _CDENTREZ_
2178 case MEDIUM_CD:
2179 case MEDIUM_DISK:
2180 return CdEntrezBiostrucFeatIds(mmdbid, feature_type, feature_set_id);
2181 #endif
2182 #ifdef _NETENTREZ_
2183 case MEDIUM_NETWORK:
2184 return NetEntrezBiostrucFeatIds(mmdbid, feature_type, feature_set_id);
2185 #endif
2186 default:
2187 return NULL;
2188 }
2189 }
2190
2191
2192 NLM_EXTERN BiostrucAnnotSetPtr LIBCALL EntrezBiostrucAnnotSetGetByFid (DocUid mmdbid, Int4 feature_id, Int4 feature_set_id)
2193 {
2194 if (! DoSelectDataSource(ENTR_SEQ_CHAN, "RECORDS", NULL)) /* SEQUENCE DATA (Abstracts) */
2195 {
2196 /* ERROR, data unobtainable */
2197 return NULL;
2198 }
2199
2200 switch (GetCurMediaType())
2201 {
2202 #ifdef _CDENTREZ_
2203 case MEDIUM_CD:
2204 case MEDIUM_DISK:
2205 return CdEntrezBiostrucAnnotSetGetByFid (mmdbid, feature_id, feature_set_id);
2206 #endif
2207 #ifdef _NETENTREZ_
2208 case MEDIUM_NETWORK:
2209 return NetEntrezBiostrucAnnotSetGetByFid (mmdbid, feature_id, feature_set_id);
2210 #endif
2211 default:
2212 return NULL;
2213 }
2214 }
2215
2216 #else
2217
2218 NLM_EXTERN BiostrucPtr LIBCALL EntrezBiostrucGet (DocUid uid, Int4 mdlLvl, Int4 maxModels)
2219 {
2220 return NULL;
2221 }
2222
2223 NLM_EXTERN BiostrucAnnotSetPtr LIBCALL EntrezBiostrucAnnotSetGet (DocUid uid)
2224 {
2225 return NULL;
2226 }
2227
2228 NLM_EXTERN LinkSetPtr LIBCALL EntrezBiostrucFeatIds(DocUid mmdbid, Int2 feature_type, Int4 feature_set_id)
2229 {
2230 return NULL;
2231 }
2232
2233 NLM_EXTERN BiostrucAnnotSetPtr LIBCALL EntrezBiostrucAnnotSetGetByFid (DocUid mmdbid, Int4 feature_id, Int4 feature_set_id)
2234 {
2235 return NULL;
2236 }
2237 #endif
2238
2239
2240
2241 /*****************************************************************************
2242 *
2243 * EntrezSeqEntryListGet (result, numuid, uids, retcode, mark_missing)
2244 * returns a count of entries read
2245 * if (mark_missing) ids which could not be located are made negative
2246 * retcode is defined in objsset.h
2247 *
2248 *****************************************************************************/
2249 NLM_EXTERN Int2 LIBCALL EntrezSeqEntryListGet (SeqEntryPtr PNTR result, Int2 numuid, Int4Ptr uids, Int2 retcode, Boolean mark_missing)
2250
2251 {
2252 Int2 obtained_ids = 0;
2253 Int4Ptr local_uids;
2254 int unmatched;
2255 Int4Ptr map;
2256 Boolean first_time;
2257 SeqEntryPtr PNTR res;
2258 Int2 i;
2259 /* DocType type; */
2260
2261 if (numuid == 0)
2262 return 0;
2263
2264 #ifdef _PMENTREZ_
2265 return PMEntSeqEntryListGet (result, numuid, uids,retcode);
2266 #else
2267
2268 first_time = TRUE;
2269
2270 if (! DoSelectDataSource(ENTR_SEQ_CHAN, "RECORDS", NULL)) /* SEQUENCE DATA (Abstracts) */
2271 {
2272 /* ERROR, data unobtainable */
2273 return 0;
2274 }
2275
2276 local_uids = (Int4Ptr) MemDup(uids, numuid * sizeof(*uids));
2277 res = (SeqEntryPtr PNTR) MemNew(numuid * sizeof(SeqEntryPtr));
2278 map = (Int4Ptr) MemNew(numuid * sizeof(Int4));
2279
2280 do {
2281 switch (GetCurMediaType())
2282 {
2283 #ifdef _CDENTREZ_
2284 case MEDIUM_CD:
2285 case MEDIUM_DISK:
2286 if (retcode == -2)
2287 obtained_ids = 0;
2288 else
2289 obtained_ids += CdEntSeqEntryListGet (res, numuid, local_uids,
2290 retcode, TRUE);
2291 #ifdef USE_IDxARCH
2292 if (retcode != -1 && obtained_ids < numuid && ConnectID())
2293 {
2294 Int2 i;
2295
2296 /* for entries which are to be explicitly retrieved from ID */
2297 if (retcode == -2)
2298 retcode = 0;
2299
2300 for (i = 0; i < numuid; i++)
2301 {
2302 if (res[i] == NULL)
2303 {
2304 if ((res[i] = IDxArchSeqEntryGet(ABS(local_uids[i]),
2305 NULL, retcode))
2306 != NULL)
2307 {
2308 local_uids[i] = ABS(local_uids[i]);
2309 obtained_ids++;
2310 }
2311 }
2312 }
2313 }
2314 #endif /* USE_IDxARCH */
2315 break;
2316 #endif
2317 #ifdef _NETENTREZ_
2318 case MEDIUM_NETWORK:
2319 obtained_ids += NetEntSeqEntryListGet (res, numuid, local_uids,
2320 retcode, TRUE);
2321 break;
2322 #endif
2323 default:
2324 break;
2325 }
2326
2327 for (unmatched = 0, i = 0; i < numuid; i++)
2328 {
2329 if (local_uids[i] >= 0) /* found this one */
2330 {
2331 if (first_time)
2332 {
2333 result[i] = res[i];
2334 }
2335 else
2336 { /* map the location */
2337 result[map[i]] = res[i];
2338 }
2339 }
2340 else {
2341 if (first_time)
2342 {
2343 result[i] = NULL;
2344 if (mark_missing)
2345 uids[i] = local_uids[i];
2346 map[unmatched] = i;
2347 }
2348 else {
2349 map[unmatched] = map[i];
2350 }
2351 local_uids[unmatched] = ABS(local_uids[i]);
2352 unmatched++;
2353 }
2354 }
2355
2356 numuid = unmatched;
2357 first_time = FALSE;
2358
2359 } while (numuid > 0 && SelectNextDataSource()); /* until we've run out of options */
2360
2361 MemFree (local_uids);
2362 MemFree (res);
2363 MemFree (map);
2364
2365 return obtained_ids;
2366 #endif
2367 }
2368
2369 /*****************************************************************************
2370 *
2371 * EntrezSeqEntryGet(uid, retcode)
2372 * get one SeqEntry
2373 *
2374 *****************************************************************************/
2375 NLM_EXTERN SeqEntryPtr EntrezSeqEntryGet (Int4 uid, Int2 retcode)
2376
2377 {
2378 SeqEntryPtr sep = NULL;
2379 ErrStrId errorID;
2380 char errorString[32];
2381
2382 if (! uid) return sep;
2383 sprintf(errorString, "(EntrezSeqEntryGet: %ld)",(long)uid);
2384 errorID = Nlm_ErrUserInstall(errorString, 0);
2385
2386 EntrezSeqEntryListGet(&sep, 1, &uid, retcode, FALSE);
2387 Nlm_ErrUserDelete(errorID);
2388 return sep;
2389 }
2390
2391 /*****************************************************************************
2392 *
2393 * EntrezFindSeqId(sip)
2394 * given a Seq-id, get the uid.
2395 * returns 0 on failure
2396 *
2397 *****************************************************************************/
2398 NLM_EXTERN Int4 LIBCALL EntrezFindSeqId (SeqIdPtr sip)
2399 {
2400 #ifdef _CDENTREZ_
2401 Int4 uid;
2402 #endif
2403
2404 #ifdef _PMENTREZ_
2405 return PMEntrezSeqIdToGI(sip);
2406 #else
2407
2408 if (sip == NULL) return 0;
2409 switch (sip->choice)
2410 {
2411 case SEQID_NOT_SET:
2412 case SEQID_LOCAL:
2413 case SEQID_OTHER:
2414 case SEQID_GENERAL:
2415 return 0;
2416 default:
2417 break;
2418 }
2419
2420 if (! DoSelectDataSourceByType(TYP_SEQ, "TERMS", NULL))
2421 {
2422 return 0;
2423 }
2424
2425 switch (GetCurMediaType())
2426 {
2427 #ifdef _CDENTREZ_
2428 case MEDIUM_CD:
2429 case MEDIUM_DISK:
2430 uid = CdEntrezFindSeqId(sip);
2431 #ifdef USE_IDxARCH
2432 if (uid == 0 && ConnectID())
2433 {
2434 TextSeqIdPtr tsip;
2435
2436 switch (sip->choice) {
2437 case SEQID_GENBANK:
2438 case SEQID_EMBL:
2439 case SEQID_PIR:
2440 case SEQID_SWISSPROT:
2441 case SEQID_DDBJ:
2442 case SEQID_PRF:
2443 case SEQID_OTHER:
2444 if ((tsip = (TextSeqIdPtr) sip->data.ptrvalue) != NULL)
2445 {
2446 if (tsip->name != NULL)
2447 {
2448 StringUpper(tsip->name);
2449 }
2450 if (tsip->accession != NULL)
2451 {
2452 StringUpper(tsip->accession);
2453 }
2454 if (sip->choice == SEQID_PIR)
2455 {
2456 if (tsip->name == NULL)
2457 { /* move accession to name */
2458 tsip->accession = tsip->name;
2459 tsip->name = NULL;
2460 } else { /* destroy accession */
2461 tsip->accession = (CharPtr) MemFree (tsip->accession);
2462 }
2463 } else {
2464 if (tsip->name != NULL && tsip->accession != NULL)
2465 {
2466 tsip->name = (CharPtr) MemFree (tsip->name);
2467 }
2468 }
2469 }
2470 break;
2471 default:
2472 break;
2473 }
2474 uid = IDxArchGIGet(sip);
2475 }
2476 #endif
2477 return uid;
2478 #endif
2479 #ifdef _NETENTREZ_
2480 case MEDIUM_NETWORK:
2481 return NetEntrezFindSeqId(sip);
2482 #endif
2483 default:
2484 return 0;
2485 }
2486 #endif /* _PMENTREZ_ */
2487
2488 }
2489
2490
2491 /*****************************************************************************
2492 *
2493 * EntrezSeqIdForGI(gi)
2494 *
2495 *****************************************************************************/
2496 NLM_EXTERN SeqIdPtr LIBCALL EntrezSeqIdForGI (Int4 gi)
2497 {
2498 SeqIdPtr sip = NULL;
2499
2500 #ifdef _PMENTREZ_
2501 return PMEntrezGIToSeqId(gi);
2502 #else
2503
2504 if (! gi) return sip;
2505
2506 if (! DoSelectDataSourceByType(TYP_SEQ, "DOCSUMS", NULL))
2507 { /* ERROR, data unobtainable */
2508 return NULL;
2509 }
2510
2511 do {
2512 switch (GetCurMediaType())
2513 {
2514 #ifdef _CDENTREZ_
2515 case MEDIUM_CD:
2516 case MEDIUM_DISK:
2517 if ((sip = CdSeqIdForGI (gi)) != NULL)
2518 return sip;
2519 break;
2520 #endif
2521 #ifdef _NETENTREZ_
2522 case MEDIUM_NETWORK:
2523 if ((sip = NetSeqIdForGI (gi)) != NULL)
2524 return sip;
2525 break;
2526 #endif
2527 default:
2528 break;
2529 }
2530 } while (SelectNextDataSource());
2531
2532 return sip;
2533
2534 #endif /* _PMENTREZ_ */
2535 }
2536
2537
2538 /*****************************************************************************
2539 *
2540 * EntrezMlSumListGet (result, numuid, uids)
2541 * returns a count of entries read
2542 * head of linked list is in result
2543 *
2544 *****************************************************************************/
2545 NLM_EXTERN Int2 LIBCALL EntrezMlSumListGet (DocSumPtr PNTR result, Int2 numuid, Int4Ptr uids)
2546
2547 {
2548 Int2 obtained_ids = 0;
2549 Int4Ptr local_uids;
2550 Int2 unmatched;
2551 Int4Ptr map;
2552 Boolean first_time = TRUE;
2553 DocSumPtr PNTR res;
2554 Int2 i;
2555
2556 if (numuid == 0)
2557 return 0;
2558
2559 if (! DoSelectDataSource(ENTR_LINKS_CHAN, ENTR_REF_CHAN, ENTR_REF_CHAN))
2560 { /* ERROR, data unobtainable */
2561 return 0;
2562 }
2563
2564 /* Iteratively try different data sources, working on an incrementally */
2565 /* reduced number of UIDs, until either docsums have been found for all */
2566 /* UIDs or, all data sources have been exhausted. The algorithm uses a */
2567 /* mapping mechanism to ensure that requests from a small subset of the */
2568 /* initial requests always map their results back to the original result */
2569 /* and uids vectors in a correct manner. */
2570
2571 local_uids = (Int4Ptr) MemDup(uids, numuid * sizeof(*uids));
2572 res = (DocSumPtr PNTR) MemNew(numuid * sizeof(DocSumPtr));
2573 map = (Int4Ptr) MemNew(numuid * sizeof(Int4));
2574
2575 do {
2576 switch (GetCurMediaType())
2577 {
2578 #ifdef _CDENTREZ_
2579 case MEDIUM_CD:
2580 case MEDIUM_DISK:
2581 #ifdef _MBENTREZ_
2582 obtained_ids = MBEntMlSumListGet (res, numuid, local_uids);
2583 break;
2584 #endif
2585 #ifdef _PMENTREZ_
2586 obtained_ids = PMEntMlSumListGet (res, numuid, local_uids);
2587 break;
2588 #else
2589 obtained_ids = CdEntMlSumListGet (res, numuid, local_uids);
2590 break;
2591 #endif /* _PMENTREZ_ */
2592
2593 #endif
2594 #ifdef _NETENTREZ_
2595 case MEDIUM_NETWORK:
2596 obtained_ids = NetDocSumListGet (res, numuid, TYP_ML, local_uids, 0);
2597 break;
2598 #endif
2599 default:
2600 break;
2601 }
2602
2603 for (unmatched = 0, i = 0; i < numuid; i++)
2604 {
2605 if (res[i] != NULL) /* found this one */
2606 {
2607 if (first_time)
2608 {
2609 result[i] = res[i];
2610 }
2611 else
2612 { /* map the location */
2613 result[map[i]] = res[i];
2614 }
2615 }
2616 else { /* not found */
2617 if (first_time)
2618 {
2619 result[i] = NULL;
2620 map[unmatched] = i;
2621 }
2622 else {
2623 map[unmatched] = map[i];
2624 }
2625 local_uids[unmatched] = local_uids[i];
2626 unmatched++;
2627 }
2628 }
2629
2630 numuid = unmatched;
2631 first_time = FALSE;
2632
2633 } while (numuid > 0 && SelectNextDataSource()); /* until we've run out of options */
2634
2635 MemFree (local_uids);
2636 MemFree (res);
2637 MemFree (map);
2638
2639 return obtained_ids;
2640 }
2641
2642 /*****************************************************************************
2643 *
2644 * EntrezSeqSumListGet (result, numuid, uids)
2645 * returns a count of entries read
2646 * head of linked list is in result
2647 *
2648 *****************************************************************************/
2649 NLM_EXTERN Int2 LIBCALL EntrezSeqSumListGet (DocSumPtr PNTR result, Int2 numuid, DocType type, Int4Ptr uids) /* Gi numbers */
2650
2651 {
2652 Int2 obtained_ids = 0;
2653 Int4Ptr local_uids;
2654 Int2 unmatched;
2655 Int4Ptr map;
2656 Boolean first_time = TRUE;
2657 DocSumPtr PNTR res;
2658 Int2 i;
2659
2660 if (numuid == 0)
2661 return 0;
2662
2663 if (! DoSelectDataSource(ENTR_LINKS_CHAN, ENTR_SEQ_CHAN, ENTR_SEQ_CHAN))
2664 { /* ERROR, data unobtainable */
2665 return 0;
2666 }
2667
2668 /* Iteratively try different data sources, working on an incrementally */
2669 /* reduced number of UIDs, until either docsums have been found for all */
2670 /* UIDs or, all data sources have been exhausted. The algorithm uses a */
2671 /* mapping mechanism to ensure that requests from a small subset of the */
2672 /* initial requests always map their results back to the original result */
2673 /* and uids vectors in a correct manner. */
2674
2675 local_uids = (Int4Ptr) MemDup(uids, numuid * sizeof(*uids));
2676 res = (DocSumPtr PNTR) MemNew(numuid * sizeof(DocSumPtr));
2677 map = (Int4Ptr) MemNew(numuid * sizeof(Int4));
2678
2679 do {
2680 switch (GetCurMediaType())
2681 {
2682 #ifdef _CDENTREZ_
2683 case MEDIUM_CD:
2684 case MEDIUM_DISK:
2685 obtained_ids = CdEntSeqSumListGet (res, numuid, type, local_uids);
2686 break;
2687 #endif
2688 #ifdef _NETENTREZ_
2689 case MEDIUM_NETWORK:
2690 obtained_ids = NetDocSumListGet (res, numuid, type, local_uids, 0);
2691 break;
2692 #endif
2693 default:
2694 break;
2695 }
2696
2697 for (unmatched = 0, i = 0; i < numuid; i++)
2698 {
2699 #ifdef USE_IDxARCH
2700 if (res[i] == NULL) /* missing this one, try again */
2701 {
2702 if ((res[i] = EntrezDocSum (type, local_uids [i])) != NULL)
2703 obtained_ids++;
2704 }
2705 #endif /* USE_IDxARCH */
2706 if (res[i] != NULL) /* found this one */
2707 {
2708 if (first_time)
2709 {
2710 result[i] = res[i];
2711 }
2712 else
2713 { /* map the location */
2714 result[map[i]] = res[i];
2715 }
2716 }
2717 else { /* not found */
2718 if (first_time)
2719 {
2720 result[i] = NULL;
2721 map[unmatched] = i;
2722 }
2723 else {
2724 map[unmatched] = map[i];
2725 }
2726 local_uids[unmatched] = local_uids[i];
2727 unmatched++;
2728 }
2729 }
2730
2731 numuid = unmatched;
2732 first_time = FALSE;
2733
2734 } while (numuid > 0 && SelectNextDataSource()); /* until we've run out of options */
2735
2736 MemFree (local_uids);
2737 MemFree (res);
2738 MemFree (map);
2739
2740 return obtained_ids;
2741 }
2742
2743 typedef struct cachedParent {
2744 CharPtr term;
2745 CharPtr parent;
2746 DocType db;
2747 DocField fld;
2748 } CachedParent, PNTR CachedParentPtr;
2749
2750 static ValNodePtr hierHead = NULL;
2751
2752 static void
2753 FreeHierarchyList(void)
2754 {
2755 ValNodePtr v;
2756 CachedParentPtr q;
2757
2758 for (v = hierHead; v != NULL; v = v->next)
2759 {
2760 q = (CachedParentPtr) v->data.ptrvalue;
2761 MemFree(q->term);
2762 MemFree(q->parent);
2763 MemFree(q);
2764 v->data.ptrvalue = NULL;
2765 }
2766 hierHead = ValNodeFree(hierHead);
2767 }
2768
2769 static EntrezHierarchyPtr DoEntrezHierarchyGet(CharPtr term, DocType db, DocField fld)
2770 {
2771 switch (GetCurMediaType())
2772 {
2773 #ifdef _CDENTREZ_
2774 case MEDIUM_CD:
2775 case MEDIUM_DISK:
2776 #ifdef _MBENTREZ_
2777 return NULL;
2778 #endif
2779 return NULL;
2780 #endif
2781
2782 #ifdef _NETENTREZ_
2783 case MEDIUM_NETWORK:
2784 return NetEntHierarchyGet(term,db,fld);
2785 #endif
2786 default:
2787 return NULL;
2788 }
2789 }
2790
2791
2792 NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyGet(CharPtr term, DocType db, DocField fld)
2793 {
2794 #ifdef _PMENTREZ_
2795
2796 return PMEntrezHierarchyGet(term,db,fld);
2797
2798 #else
2799
2800 /*
2801 if (term == NULL || (db != TYP_ML && fld != FLD_ORGN_HIER) ||
2802 (db == TYP_ML && fld != FLD_MESH_HIER))
2803 {
2804 return NULL;
2805 }
2806 */
2807
2808 return DoEntrezHierarchyGet (term,db,fld);
2809
2810 #endif
2811 }
2812
2813 NLM_EXTERN Boolean LIBCALL EntrezCanNeighborText (void)
2814 {
2815 if (! SelectDataLinksByTypes(TYP_ML, TYP_ML))
2816 { /* ERROR, data unobtainable */
2817 return FALSE;
2818 }
2819
2820 switch (GetCurMediaType())
2821 {
2822 #ifdef _CDENTREZ_
2823 case MEDIUM_CD:
2824 case MEDIUM_DISK:
2825 #ifdef _MBENTREZ_
2826 return TRUE;
2827 #endif
2828 return FALSE;
2829 #endif
2830 #ifdef _NETENTREZ_
2831 case MEDIUM_NETWORK:
2832 return NetEntCanNeighborText();
2833 #endif
2834 default:
2835 return FALSE;
2836 }
2837 }
2838
2839
2840 NLM_EXTERN LinkSetPtr LIBCALL EntrezDoNeighborText (EntrezNeighborTextPtr entp)
2841 {
2842 if (! SelectDataLinksByTypes(TYP_ML, TYP_ML))
2843 { /* ERROR, data unobtainable */
2844 return NULL;
2845 }
2846
2847 switch (GetCurMediaType()) {
2848 #ifdef _CDENTREZ_
2849 case MEDIUM_CD:
2850 case MEDIUM_DISK:
2851 #ifdef _MBENTREZ_
2852 return MBEntDoNeighborText(entp);
2853 #endif
2854 return NULL;
2855 #endif
2856 #ifdef _NETENTREZ_
2857 case MEDIUM_NETWORK:
2858 return NetEntDoNeighborText(entp);
2859 #endif
2860 default:
2861 return NULL;
2862 }
2863 }
2864
2865
2866 /**************************************************
2867 *
2868 * EntrezNeighborTextNew()
2869 *
2870 **************************************************/
2871
2872 NLM_EXTERN EntrezNeighborTextPtr LIBCALL EntrezNeighborTextNew(void)
2873 {
2874 EntrezNeighborTextPtr ptr = MemNew((size_t) sizeof(EntrezNeighborText));
2875
2876 return ptr;
2877
2878 }
2879
2880
2881 /**************************************************
2882 *
2883 * EntrezNeighborTextFree()
2884 *
2885 **************************************************/
2886
2887 NLM_EXTERN EntrezNeighborTextPtr LIBCALL EntrezNeighborTextFree(EntrezNeighborTextPtr ptr)
2888 {
2889
2890 if(ptr == NULL) {
2891 return NULL;
2892 }
2893 MemFree(ptr -> normalText);
2894 MemFree(ptr -> specialText);
2895 return MemFree(ptr);
2896 }
2897
2898
2899 NLM_EXTERN Boolean LIBCALL EntrezExpandedMedlineFeatures (void)
2900 {
2901
2902 if (! SelectDataLinksByTypes(TYP_ML, TYP_ML))
2903 { /* ERROR, data unobtainable */
2904 return FALSE;
2905 }
2906
2907 switch (GetCurMediaType())
2908 {
2909 #ifdef _CDENTREZ_
2910 case MEDIUM_CD:
2911 case MEDIUM_DISK:
2912 #ifdef _MBENTREZ_
2913 return TRUE;
2914 #endif
2915 return FALSE;
2916 #endif
2917 #ifdef _NETENTREZ_
2918 case MEDIUM_NETWORK:
2919 return NetEntExpandedMedlineFeatures();
2920 #endif
2921 default:
2922 return FALSE;
2923 }
2924 }
2925
2926
2927
2928 NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyFree(EntrezHierarchyPtr ehp)
2929 {
2930 Int2 i;
2931
2932 if (ehp == NULL)
2933 return NULL;
2934 for (i = 0; i < ehp->numInLineage; i++)
2935 MemFree (ehp->lineage[i]);
2936 MemFree (ehp->lineage);
2937 for (i = 0; i < ehp->numChildren; i++)
2938 {
2939 MemFree (ehp->children[i].name);
2940 }
2941 MemFree (ehp->children);
2942 MemFree (ehp->term);
2943 MemFree (ehp->canonicalForm);
2944 MemFree (ehp);
2945
2946 return NULL;
2947 }
2948
2949 typedef struct entrezfetch {
2950 Uint1 EntrezBioseqFetchState;
2951 CharPtr EntrezBioseqFetchAppName;
2952 Boolean is_net;
2953 Uint2 ctr; /* counts iterations of enable disable */
2954 } EntrezFetchStruct, PNTR EntrezFetchStructPtr;
2955
2956 typedef struct entrezfetchuserdata {
2957 Int4 gi;
2958 Int2 retcode;
2959 } EntrezFetchUserData, PNTR EntrezFetchUserDataPtr;
2960
2961 #define EBFS_DISABLE 0 /* EntrezBioseqFetch not in use (default) */
2962 #define EBFS_INIT 1 /* EntrezBioseqFetchEnable called, but not EntrezInit */
2963 #define EBFS_READY 2 /* EntrezInit has been called */
2964
2965 static CharPtr procname[3] = {
2966 "EntrezBioseqFetch",
2967 "EntrezSeqIdForGI",
2968 "EntrezGIForSeqId" };
2969
2970 static Int2 LIBCALLBACK EntrezBioseqFetchFunc PROTO((Pointer data));
2971 static Int2 LIBCALLBACK EntrezSeqIdForGIFunc PROTO((Pointer data));
2972 static Int2 LIBCALLBACK EntrezGIForSeqIdFunc PROTO((Pointer data));
2973
2974 /*****************************************************************************
2975 *
2976 * The Following two functions allow access by BioseqFetch using the
2977 * SeqMgr. The application should call EntrezBioseqFetchEnable() at the start
2978 * of the application and EntrezBioseqFetchDisable() at the end; This
2979 * will make EntrezBioseqFetch() the "remote" access procedure for the
2980 * SeqMgr. EntrezInit() will only be called on the first fetch unless "now"
2981 * is true;
2982 *
2983 *****************************************************************************/
2984 NLM_EXTERN Boolean LIBCALL EntrezBioseqFetchEnable(CharPtr progname, Boolean now)
2985 {
2986 Boolean result;
2987 EntrezFetchStructPtr efsp;
2988 ObjMgrPtr omp;
2989 ObjMgrProcPtr ompp;
2990
2991 /* check if already enabled ***/
2992
2993 omp = ObjMgrGet();
2994 ompp = ObjMgrProcFind(omp, 0, procname[0], OMPROC_FETCH);
2995 if (ompp != NULL) /* already initialized */
2996 efsp = (EntrezFetchStructPtr)(ompp->procdata);
2997 else
2998 {
2999 efsp = MemNew(sizeof(EntrezFetchStruct));
3000 efsp->EntrezBioseqFetchAppName = StringSave(progname);
3001
3002 ObjMgrProcLoad(OMPROC_FETCH, procname[0], procname[0], OBJ_SEQID, 0,OBJ_BIOSEQ,0,
3003 (Pointer)efsp, EntrezBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
3004
3005 ObjMgrProcLoad(OMPROC_FETCH, procname[1], procname[1], OBJ_SEQID, SEQID_GI,OBJ_SEQID,0,
3006 (Pointer)efsp, EntrezSeqIdForGIFunc, PROC_PRIORITY_DEFAULT);
3007
3008 ObjMgrProcLoad(OMPROC_FETCH, procname[2], procname[2], OBJ_SEQID, 0,OBJ_SEQID,SEQID_GI,
3009 (Pointer)efsp, EntrezGIForSeqIdFunc, PROC_PRIORITY_DEFAULT);
3010 }
3011
3012 efsp->ctr++; /* count number of enables */
3013
3014 if (efsp->EntrezBioseqFetchState == EBFS_READY) /* nothing more to do */
3015 return TRUE;
3016
3017 if (now)
3018 {
3019 result = EntrezInit(progname, TRUE, &(efsp->is_net));
3020 if (! result)
3021 {
3022 return result;
3023 }
3024 efsp->EntrezBioseqFetchState = EBFS_READY;
3025 }
3026 else
3027 efsp->EntrezBioseqFetchState = EBFS_INIT;
3028
3029
3030 return TRUE;
3031
3032 }
3033
3034 /*****************************************************************************
3035 *
3036 * EntrezBioseqFetchDisable()
3037 *
3038 *****************************************************************************/
3039 NLM_EXTERN void LIBCALL EntrezBioseqFetchDisable(void)
3040 {
3041 ObjMgrPtr omp;
3042 ObjMgrProcPtr ompp;
3043 EntrezFetchStructPtr efsp;
3044
3045 omp = ObjMgrGet();
3046 ompp = ObjMgrProcFind(omp, 0, procname[0], OMPROC_FETCH);
3047 if (ompp == NULL) /* not initialized */
3048 return;
3049
3050 efsp = (EntrezFetchStructPtr)(ompp->procdata);
3051 if (! efsp->ctr) /* no enables active */
3052 return;
3053
3054 efsp->ctr--;
3055 if (efsp->ctr) /* connection still pending */
3056 return;
3057
3058 if (efsp->EntrezBioseqFetchState == EBFS_READY)
3059 EntrezFini();
3060
3061 efsp->EntrezBioseqFetchState = EBFS_DISABLE; /* not active */
3062
3063 return;
3064 }
3065
3066 /*****************************************************************************
3067 *
3068 * EntrezFetchFreeFunc(ptr)
3069 * removes EntrezFetchUserData
3070 *
3071 *****************************************************************************/
3072 static Pointer LIBCALLBACK EntrezFetchFreeFunc (Pointer ptr)
3073 {
3074 EntrezFetchUserDataPtr efudp;
3075
3076 efudp = (EntrezFetchUserDataPtr)ptr;
3077 return MemFree(efudp);
3078 }
3079
3080 /*****************************************************************************
3081 *
3082 * EntrezBioseqFetchFunc(data)
3083 * callback for EntrezBioseqFetch
3084 *
3085 *****************************************************************************/
3086 static Int2 LIBCALLBACK EntrezBioseqFetchFunc (Pointer data)
3087 {
3088 OMProcControlPtr ompcp;
3089 ObjMgrProcPtr ompp;
3090 EntrezFetchStructPtr efsp;
3091 SeqIdPtr sip;
3092 OMUserDataPtr omdp;
3093 Boolean result;
3094 BioseqPtr bsp = NULL;
3095 Int4 gi=0;
3096 SeqEntryPtr sep;
3097 /* ValNode fake_seqid; */
3098 EntrezFetchUserDataPtr efudp;
3099 Int2 retcode=0;
3100
3101 ompcp = (OMProcControlPtr)data;
3102 ompp = ompcp->proc;
3103 efsp = (EntrezFetchStructPtr)(ompp->procdata);
3104
3105 if (efsp->EntrezBioseqFetchState == EBFS_DISABLE) /* shut off */
3106 {
3107 return OM_MSG_RET_OK; /* not done, go on to next */
3108 }
3109 else if (efsp->EntrezBioseqFetchState == EBFS_INIT)
3110 {
3111 result = EntrezInit(efsp->EntrezBioseqFetchAppName, TRUE, &(efsp->is_net));
3112 if (! result)
3113 return OM_MSG_RET_ERROR;
3114 efsp->EntrezBioseqFetchState = EBFS_READY;
3115 }
3116
3117 if (efsp->EntrezBioseqFetchState != EBFS_READY)
3118 return OM_MSG_RET_ERROR;
3119
3120 /* check for cached gi */
3121 if (ompcp->input_entityID)
3122 {
3123 omdp = ObjMgrGetUserData(ompcp->input_entityID,ompp->procid, OMPROC_FETCH, 0);
3124 if (omdp != NULL)
3125 {
3126 efudp = (EntrezFetchUserDataPtr)(omdp->userdata.ptrvalue);
3127 if (efudp != NULL)
3128 {
3129 gi = efudp->gi;
3130 retcode = efudp->retcode;
3131 }
3132 }
3133 }
3134
3135 if (! gi) /* not cached, try input id */
3136 {
3137 sip = (SeqIdPtr)(ompcp->input_data);
3138 if (sip == NULL)
3139 return OM_MSG_RET_ERROR;
3140
3141 if (sip->choice != SEQID_GI)
3142 {
3143 gi = GetUniGeneIDForSeqId(sip); /* UniGene? */
3144 if (gi) /* yes */
3145 retcode = -1;
3146 else
3147 gi = EntrezFindSeqId(sip);
3148 }
3149 else
3150 gi = sip->data.intvalue;
3151 }
3152
3153 if (! gi) return OM_MSG_RET_OK; /* no error but call next proc */
3154
3155 sep = EntrezSeqEntryGet(gi, retcode);
3156 if (sep == NULL) return OM_MSG_RET_ERROR;
3157
3158 /* if (retcode >= 0)
3159 {
3160 fake_seqid.choice = SEQID_GI;
3161 fake_seqid.data.intvalue = gi;
3162 fake_seqid.next = NULL;
3163 sip = &fake_seqid;
3164 } */
3165
3166 sip = (SeqIdPtr)(ompcp->input_data);
3167 bsp = BioseqFindInSeqEntry(sip, sep);
3168 ompcp->output_data = (Pointer)bsp;
3169 ompcp->output_entityID = ObjMgrGetEntityIDForChoice(sep);
3170
3171 /* store the cache info */
3172 omdp = ObjMgrAddUserData(ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
3173 efudp = (EntrezFetchUserDataPtr)MemNew(sizeof(EntrezFetchUserData));
3174 omdp->userdata.ptrvalue = efudp;
3175 efudp->gi = gi;
3176 efudp->retcode = retcode;
3177 omdp->freefunc = EntrezFetchFreeFunc;
3178
3179 return OM_MSG_RET_DONE; /* data found, don't call further functions */
3180 }
3181
3182 /*****************************************************************************
3183 *
3184 * EntrezSeqIdForGIFunc(data)
3185 * callback for EntrezSeqIdForGI
3186 *
3187 *****************************************************************************/
3188 static Int2 LIBCALLBACK EntrezSeqIdForGIFunc (Pointer data)
3189 {
3190 OMProcControlPtr ompcp;
3191 ObjMgrProcPtr ompp;
3192 EntrezFetchStructPtr efsp;
3193 SeqIdPtr sip, sip2;
3194 Boolean result;
3195
3196 ompcp = (OMProcControlPtr)data;
3197 ompp = ompcp->proc;
3198 efsp = (EntrezFetchStructPtr)(ompp->procdata);
3199
3200 if (efsp->EntrezBioseqFetchState == EBFS_DISABLE) /* shut off */
3201 {
3202 return OM_MSG_RET_OK; /* not done, go on to next */
3203 }
3204 else if (efsp->EntrezBioseqFetchState == EBFS_INIT)
3205 {
3206 result = EntrezInit(efsp->EntrezBioseqFetchAppName, TRUE, &(efsp->is_net));
3207 if (! result)
3208 return OM_MSG_RET_ERROR;
3209 efsp->EntrezBioseqFetchState = EBFS_READY;
3210 }
3211
3212 if (efsp->EntrezBioseqFetchState != EBFS_READY)
3213 return OM_MSG_RET_ERROR;
3214
3215 sip = (SeqIdPtr)(ompcp->input_data);
3216 if (sip == NULL)
3217 return OM_MSG_RET_ERROR;
3218 if (sip->choice != SEQID_GI)
3219 return OM_MSG_RET_ERROR;
3220
3221 sip2 = EntrezSeqIdForGI(sip->data.intvalue);
3222 if (sip2 == NULL) return OM_MSG_RET_OK;
3223
3224 ompcp->output_data = (Pointer)sip2;
3225 /* not registering right now */
3226
3227 return OM_MSG_RET_DONE; /* data found, don't call further functions */
3228 }
3229
3230 /*****************************************************************************
3231 *
3232 * EntrezGIForSeqIdFunc(data)
3233 * callback for EntrezGIForSeqId
3234 *
3235 *****************************************************************************/
3236 static Int2 LIBCALLBACK EntrezGIForSeqIdFunc (Pointer data)
3237 {
3238 OMProcControlPtr ompcp;
3239 ObjMgrProcPtr ompp;
3240 EntrezFetchStructPtr efsp;
3241 SeqIdPtr sip, sip2;
3242 Int4 gi;
3243 Boolean result;
3244
3245 ompcp = (OMProcControlPtr)data;
3246 if (ompcp == NULL)
3247 return OM_MSG_RET_ERROR;
3248
3249 sip = (SeqIdPtr)(ompcp->input_data);
3250 if (sip == NULL)
3251 return OM_MSG_RET_ERROR;
3252
3253 switch (sip->choice) {
3254 case SEQID_NOT_SET:
3255 case SEQID_LOCAL:
3256 case SEQID_OTHER:
3257 case SEQID_GENERAL:
3258 case SEQID_GI:
3259 return OM_MSG_RET_ERROR;
3260 default:
3261 break;
3262 }
3263
3264 ompp = ompcp->proc;
3265 efsp = (EntrezFetchStructPtr)(ompp->procdata);
3266
3267 if (efsp->EntrezBioseqFetchState == EBFS_DISABLE) /* shut off */
3268 {
3269 return OM_MSG_RET_OK; /* not done, go on to next */
3270 }
3271 else if (efsp->EntrezBioseqFetchState == EBFS_INIT)
3272 {
3273 result = EntrezInit(efsp->EntrezBioseqFetchAppName, TRUE, &(efsp->is_net));
3274 if (! result)
3275 return OM_MSG_RET_ERROR;
3276 efsp->EntrezBioseqFetchState = EBFS_READY;
3277 }
3278
3279 if (efsp->EntrezBioseqFetchState != EBFS_READY)
3280 return OM_MSG_RET_ERROR;
3281
3282 gi = EntrezFindSeqId(sip);
3283 if (! gi) return OM_MSG_RET_OK;
3284
3285 sip2 = ValNodeNew(NULL);
3286 sip2->choice = SEQID_GI;
3287 sip2->data.intvalue = gi;
3288
3289 ompcp->output_data = (Pointer)sip2;
3290 /* not registering right now */
3291
3292 return OM_MSG_RET_DONE; /* data found, don't call further functions */
3293 }
3294
3295 NLM_EXTERN Boolean LIBCALL EntrezCanBlast(void)
3296 {
3297 if (! SelectDataLinksByTypes(TYP_AA, TYP_AA))
3298 { /* ERROR, data unobtainable */
3299 return FALSE;
3300 }
3301
3302 switch (GetCurMediaType())
3303 {
3304 #ifdef _CDENTREZ_
3305 case MEDIUM_CD:
3306 case MEDIUM_DISK:
3307 return FALSE;
3308 #endif
3309 #ifdef _NETENTREZ_
3310 case MEDIUM_NETWORK:
3311 return NetEntCanBlast();
3312 #endif
3313 default:
3314 return FALSE;
3315 }
3316 }
3317
3318 NLM_EXTERN LinkSetPtr LIBCALL EntrezBlastBioseq(BioseqPtr bsp, DocType db, CharPtr program, CharPtr database, CharPtr options, Boolean usemonitor)
3319 {
3320 if (! SelectDataLinksByTypes(db, db))
3321 { /* ERROR, data unobtainable */
3322 return NULL;
3323 }
3324
3325 switch (GetCurMediaType()) {
3326 #ifdef _CDENTREZ_
3327 case MEDIUM_CD:
3328 case MEDIUM_DISK:
3329 return NULL;
3330 #endif
3331 #ifdef _NETENTREZ_
3332 case MEDIUM_NETWORK:
3333 return NetEntBlastBioseq(bsp, db, program, database, options, usemonitor);
3334 #endif
3335 default:
3336 return NULL;
3337 }
3338 }
3339
3340 NLM_EXTERN Int4 LIBCALL EntrezClusterAnalysis(DocUidPtr uids, Int4 numuids, DocField fld, Int4 minCluster, Int4 maxCluster, Int4 maxTerms, CharPtr *terms, Int4Ptr termTotals)
3341 {
3342
3343 if (! SelectDataLinksByTypes(TYP_ML, TYP_ML))
3344 { /* ERROR, data unobtainable */
3345 return FALSE;
3346 }
3347
3348 switch (GetCurMediaType())
3349 {
3350 #ifdef _CDENTREZ_
3351 case MEDIUM_CD:
3352 case MEDIUM_DISK:
3353 #ifdef _MBENTREZ_
3354 return MBEntrezClusterAnalysis(uids, numuids, fld, minCluster, maxCluster, maxTerms, terms, termTotals);
3355 #endif
3356 return -1;
3357 #endif
3358 #ifdef _NETENTREZ_
3359 case MEDIUM_NETWORK:
3360 return NetEntClusterAnalysis(uids, numuids, fld, minCluster, maxCluster, maxTerms, terms, termTotals);
3361 #endif
3362 default:
3363 return -1;
3364 }
3365 }
3366
3367
3368