2 * Copyright (C) 1994-1999, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.16 1999-05-26 07:49:13 adam
10 * Revision 1.15 1999/01/25 13:47:54 adam
13 * Revision 1.14 1998/11/04 16:31:32 adam
14 * Fixed bug regarding recordBytes in databaseInfo.
16 * Revision 1.13 1998/11/03 10:17:09 adam
17 * Fixed bug regarding creation of some data1 nodes for Explain records.
19 * Revision 1.12 1998/10/13 20:37:11 adam
20 * Changed the way attribute sets are saved in Explain database to
21 * reflect "dynamic" OIDs.
23 * Revision 1.11 1998/06/09 12:16:48 adam
24 * Implemented auto-generation of CategoryList records.
26 * Revision 1.10 1998/06/08 14:43:15 adam
27 * Added suport for EXPLAIN Proxy servers - added settings databasePath
28 * and explainDatabase to facilitate this. Increased maximum number
29 * of databases and attributes in one register.
31 * Revision 1.9 1998/06/02 12:10:27 adam
32 * Fixed bug related to attributeDetails.
34 * Revision 1.8 1998/05/20 10:12:20 adam
35 * Implemented automatic EXPLAIN database maintenance.
36 * Modified Zebra to work with ASN.1 compiled version of YAZ.
38 * Revision 1.7 1998/03/05 08:45:13 adam
39 * New result set model and modular ranking system. Moved towards
40 * descent server API. System information stored as "SGML" records.
42 * Revision 1.6 1998/02/17 10:29:27 adam
43 * Moved towards 'automatic' EXPLAIN database.
45 * Revision 1.5 1997/10/27 14:33:05 adam
46 * Moved towards generic character mapping depending on "structure"
47 * field in abstract syntax file. Fixed a few memory leaks. Fixed
48 * bug with negative integers when doing searches with relational
51 * Revision 1.4 1997/09/25 14:57:08 adam
54 * Revision 1.3 1996/05/22 08:21:59 adam
55 * Added public ZebDatabaseInfo structure.
57 * Revision 1.2 1996/05/14 06:16:41 adam
58 * Compact use/set bytes used in search service.
60 * Revision 1.1 1996/05/13 14:23:07 adam
61 * Work on compaction of set/use bytes in dictionary.
82 struct zebSUInfo info;
83 struct zebSUInfoB *next;
86 typedef struct zebAccessObjectB *zebAccessObject;
87 struct zebAccessObjectB {
94 typedef struct zebAccessInfoB *zebAccessInfo;
95 struct zebAccessInfoB {
96 zebAccessObject attributeSetIds;
97 zebAccessObject schemas;
101 struct zebSUInfoB *SUInfo;
105 data1_node *data1_tree;
106 } *zebAttributeDetails;
108 struct zebDatabaseInfoB {
109 zebAttributeDetails attributeDetails;
111 data1_node *data1_database;
112 int recordCount; /* records in db */
113 int recordBytes; /* size of records */
114 int sysno; /* sysno of database info */
115 int readFlag; /* 1: read is needed when referenced; 0 if not */
116 int dirty; /* 1: database is dirty: write is needed */
117 struct zebDatabaseInfoB *next;
118 zebAccessInfo accessInfo;
121 struct zebraExplainAttset {
124 struct zebraExplainAttset *next;
127 struct zebraCategoryListInfo {
130 data1_node *data1_categoryList;
133 struct zebraExplainInfo {
140 struct zebraExplainAttset *attsets;
142 data1_node *data1_target;
143 struct zebraCategoryListInfo *categoryList;
144 struct zebDatabaseInfoB *databaseInfo;
145 struct zebDatabaseInfoB *curDatabaseInfo;
146 zebAccessInfo accessInfo;
147 char date[15]; /* YYYY MMDD HH MM SS */
148 int (*updateFunc)(void *handle, Record drec, data1_node *n);
152 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
153 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
155 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
157 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
160 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
163 logf (LOG_DEBUG, "data1_search_tag %s", tag);
164 for (; n; n = n->next)
165 if (n->which == DATA1N_tag && n->u.tag.tag &&
166 !yaz_matchstr (tag, n->u.tag.tag))
168 logf (LOG_DEBUG, " found");
171 logf (LOG_DEBUG, " not found");
175 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
176 const char *tag, NMEM nmem)
178 data1_node *partag = get_parent_tag(dh, at);
179 data1_node *res = data1_mk_node (dh, nmem);
180 data1_element *e = NULL;
183 res->which = DATA1N_tag;
184 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
185 res->u.tag.node_selected = 0;
186 res->u.tag.make_variantlist = 0;
187 res->u.tag.no_data_requested = 0;
188 res->u.tag.get_bytes = -1;
191 e = partag->u.tag.element;
193 data1_getelementbytagname (dh, at->root->u.root.absyn,
195 res->root = at->root;
200 assert (at->last_child);
201 at->last_child->next = res;
203 at->last_child = res;
207 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
208 const char *tag, NMEM nmem)
210 data1_node *node = data1_search_tag (dh, at->child, tag);
212 node = data1_add_tag (dh, at, tag, nmem);
214 node->child = node->last_child = NULL;
218 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
219 const char *tag, int num,
222 data1_node *node_data;
224 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
227 node_data->u.data.what = DATA1I_num;
228 node_data->u.data.data = node_data->lbuf;
229 sprintf (node_data->u.data.data, "%d", num);
230 node_data->u.data.len = strlen (node_data->u.data.data);
234 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
235 const char *tag, Odr_oid *oid,
238 data1_node *node_data;
239 char str[128], *p = str;
242 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
246 for (ii = oid; *ii >= 0; ii++)
250 sprintf (p, "%d", *ii);
253 node_data->u.data.what = DATA1I_oid;
254 node_data->u.data.len = strlen (str);
255 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
260 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
261 const char *tag, const char *str,
264 data1_node *node_data;
266 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
269 node_data->u.data.what = DATA1I_text;
270 node_data->u.data.len = strlen (str);
271 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
275 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
276 const char *tag, const char *str,
279 data1_node *node = data1_search_tag (dh, at->child, tag);
281 return data1_add_tagdata_text (dh, at, tag, str, nmem);
284 data1_node *node_data = node->child;
285 node_data->u.data.what = DATA1I_text;
286 node_data->u.data.len = strlen (str);
287 node_data->u.data.data = data1_insert_string (dh, node_data,
293 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
294 struct zebDatabaseInfoB *zdi,
296 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
297 zebAttributeDetails zad,
298 const char *databaseName,
300 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
301 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
304 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
305 struct zebraCategoryListInfo *zcl,
309 static Record createRecord (Records records, int *sysno)
314 rec = rec_get (records, *sysno);
315 xfree (rec->info[recInfo_storeData]);
319 rec = rec_new (records);
322 rec->info[recInfo_fileType] =
323 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
324 rec->info[recInfo_databaseName] =
325 rec_strdup ("IR-Explain-1",
326 &rec->size[recInfo_databaseName]);
331 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag,
332 int (*updateH)(Record drec, data1_node *n))
334 struct zebDatabaseInfoB *zdi;
336 logf (LOG_DEBUG, "zebraExplain_close wr=%d", writeFlag);
340 /* write each database info record */
341 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
343 zebraExplain_writeDatabase (zei, zdi, 1);
344 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
345 zdi->databaseName, 1);
347 zebraExplain_writeTarget (zei, 1);
348 zebraExplain_writeCategoryList (zei,
351 assert (zei->accessInfo);
352 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
354 zebraExplain_writeAttributeSet (zei, o, 1);
355 for (o = zei->accessInfo->schemas; o; o = o->next)
358 /* zebraExplain_writeSchema (zei, o, 1); */
361 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
363 zebraExplain_writeDatabase (zei, zdi, 0);
364 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
365 zdi->databaseName, 0);
367 zebraExplain_writeTarget (zei, 0);
370 nmem_destroy (zei->nmem);
374 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
379 for (np = n->child; np; np = np->next)
386 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
388 len = np->child->u.data.len;
391 memcpy (str, np->child->u.data.data, len);
394 oid = odr_getoidbystr_nmem (zei->nmem, str);
396 for (ao = *op; ao; ao = ao->next)
397 if (!oid_oidcmp (oid, ao->oid))
404 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
414 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
415 zebAccessInfo *accessInfo)
421 *accessInfo = (zebAccessInfo)
422 nmem_malloc (zei->nmem, sizeof(**accessInfo));
423 (*accessInfo)->attributeSetIds = NULL;
424 (*accessInfo)->schemas = NULL;
428 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
430 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
431 zebraExplain_mergeOids (zei, np,
432 &(*accessInfo)->attributeSetIds);
433 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
434 zebraExplain_mergeOids (zei, np,
435 &(*accessInfo)->schemas);
439 ZebraExplainInfo zebraExplain_open (
440 Records records, data1_handle dh,
444 int (*updateFunc)(void *handle, Record drec, data1_node *n))
447 ZebraExplainInfo zei;
448 struct zebDatabaseInfoB **zdip;
452 logf (LOG_DEBUG, "zebraExplain_open wr=%d", writeFlag);
453 zei = (ZebraExplainInfo) xmalloc (sizeof(*zei));
454 zei->updateHandle = updateHandle;
455 zei->updateFunc = updateFunc;
457 zei->curDatabaseInfo = NULL;
458 zei->records = records;
459 zei->nmem = nmem_create ();
463 zei->categoryList = (struct zebraCategoryListInfo *)
464 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
465 zei->categoryList->sysno = 0;
466 zei->categoryList->dirty = 0;
467 zei->categoryList->data1_categoryList = NULL;
470 tm = localtime (&our_time);
471 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
472 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
473 tm->tm_hour, tm->tm_min, tm->tm_sec);
475 zdip = &zei->databaseInfo;
476 trec = rec_get (records, 1); /* get "root" record */
478 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
479 if (trec) /* targetInfo already exists ... */
481 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
483 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
486 data1_pr_tree (zei->dh, zei->data1_target, stderr);
488 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
490 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
493 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
495 node_list = data1_search_tag (zei->dh, node_zebra->child,
497 for (np = node_list->child; np; np = np->next)
499 data1_node *node_name = NULL;
500 data1_node *node_id = NULL;
501 data1_node *node_aid = NULL;
503 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
505 for (np2 = np->child; np2; np2 = np2->next)
507 if (np2->which != DATA1N_tag)
509 if (!strcmp (np2->u.tag.tag, "name"))
510 node_name = np2->child;
511 else if (!strcmp (np2->u.tag.tag, "id"))
512 node_id = np2->child;
513 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
514 node_aid = np2->child;
516 assert (node_id && node_name && node_aid);
518 *zdip = (struct zebDatabaseInfoB *)
519 nmem_malloc (zei->nmem, sizeof(**zdip));
520 (*zdip)->readFlag = 1;
522 (*zdip)->data1_database = NULL;
523 (*zdip)->recordCount = 0;
524 (*zdip)->recordBytes = 0;
525 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
527 (*zdip)->databaseName = (char *)
528 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
529 memcpy ((*zdip)->databaseName, node_name->u.data.data,
530 node_name->u.data.len);
531 (*zdip)->databaseName[node_name->u.data.len] = '\0';
532 (*zdip)->sysno = atoi_n (node_id->u.data.data,
533 node_id->u.data.len);
534 (*zdip)->attributeDetails = (zebAttributeDetails)
535 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
536 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
537 node_aid->u.data.len);
538 (*zdip)->attributeDetails->readFlag = 1;
539 (*zdip)->attributeDetails->dirty = 0;
540 (*zdip)->attributeDetails->SUInfo = NULL;
542 zdip = &(*zdip)->next;
544 np = data1_search_tag (zei->dh, node_zebra->child,
547 assert (np && np->which == DATA1N_data);
548 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
550 np = data1_search_tag (zei->dh, node_zebra->child,
553 assert (np && np->which == DATA1N_data);
554 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
558 else /* create initial targetInfo */
560 data1_node *node_tgtinfo;
570 data1_read_sgml (zei->dh, zei->nmem,
571 "<explain><targetInfo>TargetInfo\n"
573 "<namedResultSets>1</>\n"
574 "<multipleDBSearch>1</>\n"
575 "<nicknames><name>Zebra</></>\n"
578 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
580 assert (node_tgtinfo);
582 zebraExplain_initCommonInfo (zei, node_tgtinfo);
583 zebraExplain_initAccessInfo (zei, node_tgtinfo);
585 /* write now because we want to be sure about the sysno */
586 trec = rec_new (records);
587 trec->info[recInfo_fileType] =
588 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
589 trec->info[recInfo_databaseName] =
590 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
592 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
593 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
594 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
595 trec->size[recInfo_storeData] = sgml_len;
597 rec_put (records, &trec);
601 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
603 if (!zei->categoryList->dirty)
605 struct zebraCategoryListInfo *zcl = zei->categoryList;
609 zcl->data1_categoryList =
610 data1_read_sgml (zei->dh, zei->nmem,
611 "<explain><categoryList>CategoryList\n"
613 node_cl = data1_search_tag (zei->dh,
614 zcl->data1_categoryList->child,
617 zebraExplain_initCommonInfo (zei, node_cl);
623 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
624 zebAttributeDetails zad)
627 struct zebSUInfoB **zsuip = &zad->SUInfo;
628 data1_node *node_adinfo, *node_zebra, *node_list, *np;
631 rec = rec_get (zei->records, zad->sysno);
633 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
635 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
637 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
639 node_list = data1_search_tag (zei->dh, node_zebra->child,
641 for (np = node_list->child; np; np = np->next)
643 data1_node *node_set = NULL;
644 data1_node *node_use = NULL;
645 data1_node *node_ordinal = NULL;
650 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
652 for (np2 = np->child; np2; np2 = np2->next)
654 if (np2->which != DATA1N_tag || !np2->child ||
655 np2->child->which != DATA1N_data)
657 if (!strcmp (np2->u.tag.tag, "set"))
658 node_set = np2->child;
659 else if (!strcmp (np2->u.tag.tag, "use"))
660 node_use = np2->child;
661 else if (!strcmp (np2->u.tag.tag, "ordinal"))
662 node_ordinal = np2->child;
664 assert (node_set && node_use && node_ordinal);
666 oid_str_len = node_set->u.data.len;
667 if (oid_str_len >= (int) sizeof(oid_str))
668 oid_str_len = sizeof(oid_str)-1;
669 memcpy (oid_str, node_set->u.data.data, oid_str_len);
670 oid_str[oid_str_len] = '\0';
672 *zsuip = (struct zebSUInfoB *)
673 nmem_malloc (zei->nmem, sizeof(**zsuip));
674 (*zsuip)->info.set = oid_getvalbyname (oid_str);
676 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
677 node_use->u.data.len);
678 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
679 node_ordinal->u.data.len);
680 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
681 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
682 zsuip = &(*zsuip)->next;
689 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
690 struct zebDatabaseInfoB *zdi)
693 data1_node *node_dbinfo, *node_zebra, *np;
696 rec = rec_get (zei->records, zdi->sysno);
698 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
700 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
702 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
704 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
707 && (np = data1_search_tag (zei->dh, node_zebra->child,
709 && np->child && np->child->which == DATA1N_data)
710 zdi->recordBytes = atoi_n (np->child->u.data.data,
711 np->child->u.data.len);
712 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
714 (np = data1_search_tag (zei->dh, np->child,
715 "recordCountActual")) &&
716 np->child->which == DATA1N_data)
718 zdi->recordCount = atoi_n (np->child->u.data.data,
719 np->child->u.data.len);
725 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
727 struct zebDatabaseInfoB *zdi;
730 if (zei->curDatabaseInfo &&
731 !strcmp (zei->curDatabaseInfo->databaseName, database))
733 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
735 if (!strcmp (zdi->databaseName, database))
741 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
746 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
748 zebraExplain_readDatabase (zei, zdi);
750 if (zdi->attributeDetails->readFlag)
753 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
755 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
757 zei->curDatabaseInfo = zdi;
761 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
763 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
765 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
766 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
767 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
770 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
772 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
774 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
777 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
779 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
780 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
781 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
784 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
785 zebAccessInfo accessInfo)
787 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
793 if ((p = accessInfo->attributeSetIds))
795 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
796 for (; p; p = p->next)
797 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
799 if ((p = accessInfo->schemas))
801 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
802 for (; p; p = p->next)
803 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
807 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
808 int explain_database)
810 struct zebDatabaseInfoB *zdi;
811 data1_node *node_dbinfo, *node_adinfo;
814 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
817 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
819 if (!strcmp (zdi->databaseName, database))
824 /* it's new really. make it */
825 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
826 zdi->next = zei->databaseInfo;
827 zei->databaseInfo = zdi;
829 zdi->recordCount = 0;
830 zdi->recordBytes = 0;
832 zdi->databaseName = nmem_strdup (zei->nmem, database);
834 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
839 zdi->data1_database =
840 data1_read_sgml (zei->dh, zei->nmem,
841 "<explain><databaseInfo>DatabaseInfo\n"
844 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
846 assert (node_dbinfo);
848 zebraExplain_initCommonInfo (zei, node_dbinfo);
849 zebraExplain_initAccessInfo (zei, node_dbinfo);
851 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
852 database, zei->nmem);
854 if (explain_database)
855 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
858 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
861 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
865 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
869 zei->curDatabaseInfo = zdi;
871 zdi->attributeDetails = (zebAttributeDetails)
872 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
873 zdi->attributeDetails->readFlag = 0;
874 zdi->attributeDetails->sysno = 0;
875 zdi->attributeDetails->dirty = 1;
876 zdi->attributeDetails->SUInfo = NULL;
877 zdi->attributeDetails->data1_tree =
878 data1_read_sgml (zei->dh, zei->nmem,
879 "<explain><attributeDetails>AttributeDetails\n"
883 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
885 assert (node_adinfo);
887 zebraExplain_initCommonInfo (zei, node_adinfo);
892 static void writeAttributeValueDetails (ZebraExplainInfo zei,
893 zebAttributeDetails zad,
894 data1_node *node_atvs, data1_attset *attset)
897 struct zebSUInfoB *zsui;
898 int set_ordinal = attset->reference;
899 data1_attset_child *c;
901 for (c = attset->children; c; c = c->next)
902 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
903 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
905 data1_node *node_attvalue, *node_value;
906 if (set_ordinal != zsui->info.set)
908 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
910 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
912 data1_add_tagdata_int (zei->dh, node_value, "numeric",
913 zsui->info.use, zei->nmem);
917 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
918 struct zebraCategoryListInfo *zcl,
925 data1_node *node_ci, *node_categoryList;
927 static char *category[] = {
939 node_categoryList = zcl->data1_categoryList;
942 logf (LOG_LOG, "zebraExplain_writeCategoryList");
945 drec = createRecord (zei->records, &sysno);
947 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
950 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
953 for (i = 0; category[i]; i++)
955 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
956 "category", zei->nmem);
958 data1_add_tagdata_text (zei->dh, node_cat, "name",
959 category[i], zei->nmem);
961 /* extract *searchable* keys from it. We do this here, because
962 record count, etc. is affected */
964 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
966 /* convert to "SGML" and write it */
968 data1_pr_tree (zei->dh, node_categoryList, stderr);
970 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
971 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
972 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
973 drec->size[recInfo_storeData] = sgml_len;
975 rec_put (zei->records, &drec);
978 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
979 zebAttributeDetails zad,
980 const char *databaseName,
986 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
987 struct zebSUInfoB *zsui;
995 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
998 drec = createRecord (zei->records, &zad->sysno);
999 assert (zad->data1_tree);
1000 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
1001 "attributeDetails");
1002 zebraExplain_updateCommonInfo (zei, node_adinfo);
1004 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
1005 databaseName, zei->nmem);
1007 /* extract *searchable* keys from it. We do this here, because
1008 record count, etc. is affected */
1010 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1012 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
1013 "attributesBySet", zei->nmem);
1017 data1_node *node_asd;
1018 data1_attset *attset;
1019 int set_ordinal = -1;
1020 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1022 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1023 && zsui->info.set > set_min)
1024 set_ordinal = zsui->info.set;
1026 if (set_ordinal < 0)
1028 set_min = set_ordinal;
1029 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1030 "attributeSetDetails", zei->nmem);
1032 attset = data1_attset_search_id (zei->dh, set_ordinal);
1035 zebraExplain_loadAttsets (zei->dh, zei->res);
1036 attset = data1_attset_search_id (zei->dh, set_ordinal);
1043 oe.proto = PROTO_Z3950;
1044 oe.oclass = CLASS_ATTSET;
1045 oe.value = (enum oid_value) set_ordinal;
1047 if (oid_ent_to_oid (&oe, oid))
1049 data1_node *node_abt, *node_atd, *node_atvs;
1050 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1053 node_abt = data1_add_tag (zei->dh, node_asd,
1054 "attributesByType", zei->nmem);
1055 node_atd = data1_add_tag (zei->dh, node_abt,
1056 "attributeTypeDetails", zei->nmem);
1057 data1_add_tagdata_int (zei->dh, node_atd,
1058 "type", 1, zei->nmem);
1059 node_atvs = data1_add_tag (zei->dh, node_atd,
1060 "attributeValues", zei->nmem);
1061 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1065 /* zebra info (private) */
1066 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1067 "zebraInfo", zei->nmem);
1068 node_list = data1_make_tag (zei->dh, node_zebra,
1069 "attrlist", zei->nmem);
1070 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1072 struct oident oident;
1074 data1_node *node_attr;
1076 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1078 oident.proto = PROTO_Z3950;
1079 oident.oclass = CLASS_ATTSET;
1080 oident.value = (enum oid_value) zsui->info.set;
1081 oid_ent_to_oid (&oident, oid);
1083 data1_add_tagdata_text (zei->dh, node_attr, "set",
1084 oident.desc, zei->nmem);
1085 data1_add_tagdata_int (zei->dh, node_attr, "use",
1086 zsui->info.use, zei->nmem);
1087 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1088 zsui->info.ordinal, zei->nmem);
1090 /* convert to "SGML" and write it */
1092 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1094 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1096 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1097 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1098 drec->size[recInfo_storeData] = sgml_len;
1100 rec_put (zei->records, &drec);
1103 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1104 struct zebDatabaseInfoB *zdi,
1110 data1_node *node_dbinfo, *node_count, *node_zebra;
1117 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1119 drec = createRecord (zei->records, &zdi->sysno);
1120 assert (zdi->data1_database);
1121 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1124 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1125 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1127 /* extract *searchable* keys from it. We do this here, because
1128 record count, etc. is affected */
1130 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1132 node_count = data1_make_tag (zei->dh, node_dbinfo,
1133 "recordCount", zei->nmem);
1134 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1135 zdi->recordCount, zei->nmem);
1137 /* zebra info (private) */
1138 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1139 "zebraInfo", zei->nmem);
1140 data1_add_tagdata_int (zei->dh, node_zebra,
1141 "recordBytes", zdi->recordBytes, zei->nmem);
1142 /* convert to "SGML" and write it */
1144 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1146 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1148 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1149 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1150 drec->size[recInfo_storeData] = sgml_len;
1152 rec_put (zei->records, &drec);
1155 static void writeAttributeValues (ZebraExplainInfo zei,
1156 data1_node *node_values,
1157 data1_attset *attset)
1160 data1_attset_child *c;
1165 for (c = attset->children; c; c = c->next)
1166 writeAttributeValues (zei, node_values, c->child);
1167 for (atts = attset->atts; atts; atts = atts->next)
1169 data1_node *node_value;
1171 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1173 data1_add_tagdata_text (zei->dh, node_value, "name",
1174 atts->name, zei->nmem);
1175 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1176 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1177 atts->value, zei->nmem);
1182 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1189 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1190 data1_node *node_values;
1191 struct oident *entp;
1192 struct data1_attset *attset = NULL;
1194 if ((entp = oid_getentbyoid (o->oid)))
1195 attset = data1_attset_search_id (zei->dh, entp->value);
1198 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1199 attset ? attset->name : "<unknown>");
1202 drec = createRecord (zei->records, &o->sysno);
1204 data1_read_sgml (zei->dh, zei->nmem,
1205 "<explain><attributeSetInfo>AttributeSetInfo\n"
1208 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1209 "attributeSetInfo");
1211 zebraExplain_initCommonInfo (zei, node_attinfo);
1212 zebraExplain_updateCommonInfo (zei, node_attinfo);
1214 data1_add_tagdata_oid (zei->dh, node_attinfo,
1215 "oid", o->oid, zei->nmem);
1216 if (attset && attset->name)
1217 data1_add_tagdata_text (zei->dh, node_attinfo,
1218 "name", attset->name, zei->nmem);
1220 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1221 "attributes", zei->nmem);
1222 node_atttype = data1_make_tag (zei->dh, node_attributes,
1223 "attributeType", zei->nmem);
1224 data1_add_tagdata_text (zei->dh, node_atttype,
1225 "name", "Use", zei->nmem);
1226 data1_add_tagdata_text (zei->dh, node_atttype,
1227 "description", "Use Attribute", zei->nmem);
1228 data1_add_tagdata_int (zei->dh, node_atttype,
1229 "type", 1, zei->nmem);
1230 node_values = data1_add_tag (zei->dh, node_atttype,
1231 "attributeValues", zei->nmem);
1233 writeAttributeValues (zei, node_values, attset);
1235 /* extract *searchable* keys from it. We do this here, because
1236 record count, etc. is affected */
1238 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1239 /* convert to "SGML" and write it */
1241 data1_pr_tree (zei->dh, node_root, stderr);
1243 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1244 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1245 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1246 drec->size[recInfo_storeData] = sgml_len;
1248 rec_put (zei->records, &drec);
1251 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1253 struct zebDatabaseInfoB *zdi;
1254 data1_node *node_tgtinfo, *node_list, *node_zebra;
1263 trec = rec_get (zei->records, 1);
1264 xfree (trec->info[recInfo_storeData]);
1266 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1268 assert (node_tgtinfo);
1270 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1271 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1273 /* convert to "SGML" and write it */
1275 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1277 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1278 "zebraInfo", zei->nmem);
1279 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1280 ZEBRAVER, zei->nmem);
1281 node_list = data1_add_tag (zei->dh, node_zebra,
1282 "databaseList", zei->nmem);
1283 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1285 data1_node *node_db;
1286 node_db = data1_add_tag (zei->dh, node_list,
1287 "database", zei->nmem);
1288 data1_add_tagdata_text (zei->dh, node_db, "name",
1289 zdi->databaseName, zei->nmem);
1290 data1_add_tagdata_int (zei->dh, node_db, "id",
1291 zdi->sysno, zei->nmem);
1292 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1293 zdi->attributeDetails->sysno, zei->nmem);
1295 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1296 zei->ordinalSU, zei->nmem);
1298 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1299 zei->runNumber, zei->nmem);
1302 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1304 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1306 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1307 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1308 trec->size[recInfo_storeData] = sgml_len;
1310 rec_put (zei->records, &trec);
1313 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1315 struct zebSUInfoB *zsui;
1317 assert (zei->curDatabaseInfo);
1318 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1319 zsui; zsui=zsui->next)
1320 if (zsui->info.use == use && zsui->info.set == set)
1321 return zsui->info.ordinal;
1325 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1326 zebAccessObject *op,
1331 for (ao = *op; ao; ao = ao->next)
1332 if (!oid_oidcmp (oid, ao->oid))
1336 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1339 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1346 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1351 oe.proto = PROTO_Z3950;
1352 oe.oclass = CLASS_ATTSET;
1353 oe.value = (enum oid_value) set;
1355 if (oid_ent_to_oid (&oe, oid))
1357 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1358 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1359 accessInfo->attributeSetIds, oid);
1363 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1365 struct zebSUInfoB *zsui;
1367 assert (zei->curDatabaseInfo);
1368 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1369 zsui; zsui=zsui->next)
1370 if (zsui->info.use == use && zsui->info.set == set)
1372 zebraExplain_addAttributeSet (zei, set);
1373 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1374 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1375 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1376 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1378 zsui->info.set = set;
1379 zsui->info.use = use;
1380 zsui->info.ordinal = (zei->ordinalSU)++;
1381 return zsui->info.ordinal;
1384 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1386 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1387 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1388 accessInfo->schemas, oid);
1391 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1393 assert (zei->curDatabaseInfo);
1397 zei->curDatabaseInfo->recordBytes += adjust_num;
1398 zei->curDatabaseInfo->dirty = 1;
1402 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1404 assert (zei->curDatabaseInfo);
1408 zei->curDatabaseInfo->recordCount += adjust_num;
1409 zei->curDatabaseInfo->dirty = 1;
1413 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1417 return zei->runNumber += adjust_num;
1420 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1422 RecordAttr *recordAttr;
1424 if (rec->info[recInfo_attr])
1425 return (RecordAttr *) rec->info[recInfo_attr];
1426 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1427 rec->info[recInfo_attr] = (char *) recordAttr;
1428 rec->size[recInfo_attr] = sizeof(*recordAttr);
1430 recordAttr->recordSize = 0;
1431 recordAttr->recordOffset = 0;
1432 recordAttr->runNumber = zei->runNumber;
1436 static void att_loadset(void *p, const char *n, const char *name)
1438 data1_handle dh = (data1_handle) p;
1439 if (!data1_get_attset (dh, name))
1440 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1443 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1445 res_trav(res, "attset", dh, att_loadset);
1449 zebraExplain_addSU adds to AttributeDetails for a database and
1450 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1451 exist for the database.
1453 If the database doesn't exist globally (in TargetInfo) an
1454 AttributeSetInfo must be added (globally).