2 * Copyright (C) 1994-1998, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.13 1998-11-03 10:17:09 adam
8 * Fixed bug regarding creation of some data1 nodes for Explain records.
10 * Revision 1.12 1998/10/13 20:37:11 adam
11 * Changed the way attribute sets are saved in Explain database to
12 * reflect "dynamic" OIDs.
14 * Revision 1.11 1998/06/09 12:16:48 adam
15 * Implemented auto-generation of CategoryList records.
17 * Revision 1.10 1998/06/08 14:43:15 adam
18 * Added suport for EXPLAIN Proxy servers - added settings databasePath
19 * and explainDatabase to facilitate this. Increased maximum number
20 * of databases and attributes in one register.
22 * Revision 1.9 1998/06/02 12:10:27 adam
23 * Fixed bug related to attributeDetails.
25 * Revision 1.8 1998/05/20 10:12:20 adam
26 * Implemented automatic EXPLAIN database maintenance.
27 * Modified Zebra to work with ASN.1 compiled version of YAZ.
29 * Revision 1.7 1998/03/05 08:45:13 adam
30 * New result set model and modular ranking system. Moved towards
31 * descent server API. System information stored as "SGML" records.
33 * Revision 1.6 1998/02/17 10:29:27 adam
34 * Moved towards 'automatic' EXPLAIN database.
36 * Revision 1.5 1997/10/27 14:33:05 adam
37 * Moved towards generic character mapping depending on "structure"
38 * field in abstract syntax file. Fixed a few memory leaks. Fixed
39 * bug with negative integers when doing searches with relational
42 * Revision 1.4 1997/09/25 14:57:08 adam
45 * Revision 1.3 1996/05/22 08:21:59 adam
46 * Added public ZebDatabaseInfo structure.
48 * Revision 1.2 1996/05/14 06:16:41 adam
49 * Compact use/set bytes used in search service.
51 * Revision 1.1 1996/05/13 14:23:07 adam
52 * Work on compaction of set/use bytes in dictionary.
73 struct zebSUInfo info;
74 struct zebSUInfoB *next;
77 typedef struct zebAccessObjectB *zebAccessObject;
78 struct zebAccessObjectB {
85 typedef struct zebAccessInfoB *zebAccessInfo;
86 struct zebAccessInfoB {
87 zebAccessObject attributeSetIds;
88 zebAccessObject schemas;
92 struct zebSUInfoB *SUInfo;
96 data1_node *data1_tree;
97 } *zebAttributeDetails;
99 struct zebDatabaseInfoB {
100 zebAttributeDetails attributeDetails;
102 data1_node *data1_database;
103 int recordCount; /* records in db */
104 int recordBytes; /* size of records */
105 int sysno; /* sysno of database info */
106 int readFlag; /* 1: read is needed when referenced; 0 if not */
107 int dirty; /* 1: database is dirty: write is needed */
108 struct zebDatabaseInfoB *next;
109 zebAccessInfo accessInfo;
112 struct zebraExplainAttset {
115 struct zebraExplainAttset *next;
118 struct zebraCategoryListInfo {
121 data1_node *data1_categoryList;
124 struct zebraExplainInfo {
131 struct zebraExplainAttset *attsets;
133 data1_node *data1_target;
134 struct zebraCategoryListInfo *categoryList;
135 struct zebDatabaseInfoB *databaseInfo;
136 struct zebDatabaseInfoB *curDatabaseInfo;
137 zebAccessInfo accessInfo;
138 char date[15]; /* YYYY MMDD HH MM SS */
139 int (*updateFunc)(void *handle, Record drec, data1_node *n);
143 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
144 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
146 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
148 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
151 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
154 logf (LOG_DEBUG, "data1_search_tag %s", tag);
155 for (; n; n = n->next)
156 if (n->which == DATA1N_tag && n->u.tag.tag &&
157 !yaz_matchstr (tag, n->u.tag.tag))
159 logf (LOG_DEBUG, " found");
162 logf (LOG_DEBUG, " not found");
166 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
167 const char *tag, NMEM nmem)
169 data1_node *partag = get_parent_tag(dh, at);
170 data1_node *res = data1_mk_node (dh, nmem);
171 data1_element *e = NULL;
174 res->which = DATA1N_tag;
175 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
176 res->u.tag.node_selected = 0;
177 res->u.tag.make_variantlist = 0;
178 res->u.tag.no_data_requested = 0;
179 res->u.tag.get_bytes = -1;
182 e = partag->u.tag.element;
184 data1_getelementbytagname (dh, at->root->u.root.absyn,
186 res->root = at->root;
191 assert (at->last_child);
192 at->last_child->next = res;
194 at->last_child = res;
198 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
199 const char *tag, NMEM nmem)
201 data1_node *node = data1_search_tag (dh, at->child, tag);
203 node = data1_add_tag (dh, at, tag, nmem);
205 node->child = node->last_child = NULL;
209 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
210 const char *tag, int num,
213 data1_node *node_data;
215 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
218 node_data->u.data.what = DATA1I_num;
219 node_data->u.data.data = node_data->lbuf;
220 sprintf (node_data->u.data.data, "%d", num);
221 node_data->u.data.len = strlen (node_data->u.data.data);
225 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
226 const char *tag, Odr_oid *oid,
229 data1_node *node_data;
230 char str[128], *p = str;
233 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
237 for (ii = oid; *ii >= 0; ii++)
241 sprintf (p, "%d", *ii);
244 node_data->u.data.what = DATA1I_oid;
245 node_data->u.data.len = strlen (str);
246 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
251 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
252 const char *tag, const char *str,
255 data1_node *node_data;
257 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
260 node_data->u.data.what = DATA1I_text;
261 node_data->u.data.len = strlen (str);
262 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
266 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
267 const char *tag, const char *str,
270 data1_node *node = data1_search_tag (dh, at->child, tag);
272 return data1_add_tagdata_text (dh, at, tag, str, nmem);
275 data1_node *node_data = node->child;
276 node_data->u.data.what = DATA1I_text;
277 node_data->u.data.len = strlen (node_data->u.data.data);
278 node_data->u.data.data = data1_insert_string (dh, node_data,
284 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
285 struct zebDatabaseInfoB *zdi,
287 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
288 zebAttributeDetails zad,
289 const char *databaseName,
291 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
292 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
295 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
296 struct zebraCategoryListInfo *zcl,
300 static Record createRecord (Records records, int *sysno)
305 rec = rec_get (records, *sysno);
306 xfree (rec->info[recInfo_storeData]);
310 rec = rec_new (records);
313 rec->info[recInfo_fileType] =
314 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
315 rec->info[recInfo_databaseName] =
316 rec_strdup ("IR-Explain-1",
317 &rec->size[recInfo_databaseName]);
322 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag,
323 int (*updateH)(Record drec, data1_node *n))
325 struct zebDatabaseInfoB *zdi;
327 logf (LOG_DEBUG, "zebraExplain_close wr=%d", writeFlag);
331 /* write each database info record */
332 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
334 zebraExplain_writeDatabase (zei, zdi, 1);
335 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
336 zdi->databaseName, 1);
338 zebraExplain_writeTarget (zei, 1);
339 zebraExplain_writeCategoryList (zei,
342 assert (zei->accessInfo);
343 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
345 zebraExplain_writeAttributeSet (zei, o, 1);
346 for (o = zei->accessInfo->schemas; o; o = o->next)
349 /* zebraExplain_writeSchema (zei, o, 1); */
352 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
354 zebraExplain_writeDatabase (zei, zdi, 0);
355 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
356 zdi->databaseName, 0);
358 zebraExplain_writeTarget (zei, 0);
361 nmem_destroy (zei->nmem);
365 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
370 for (np = n->child; np; np = np->next)
377 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
379 len = np->child->u.data.len;
382 memcpy (str, np->child->u.data.data, len);
385 oid = odr_getoidbystr_nmem (zei->nmem, str);
387 for (ao = *op; ao; ao = ao->next)
388 if (!oid_oidcmp (oid, ao->oid))
395 ao = nmem_malloc (zei->nmem, sizeof(*ao));
405 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
406 zebAccessInfo *accessInfo)
412 *accessInfo = nmem_malloc (zei->nmem, sizeof(**accessInfo));
413 (*accessInfo)->attributeSetIds = NULL;
414 (*accessInfo)->schemas = NULL;
418 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
420 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
421 zebraExplain_mergeOids (zei, np,
422 &(*accessInfo)->attributeSetIds);
423 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
424 zebraExplain_mergeOids (zei, np,
425 &(*accessInfo)->schemas);
429 ZebraExplainInfo zebraExplain_open (
430 Records records, data1_handle dh,
434 int (*updateFunc)(void *handle, Record drec, data1_node *n))
437 ZebraExplainInfo zei;
438 struct zebDatabaseInfoB **zdip;
442 logf (LOG_DEBUG, "zebraExplain_open wr=%d", writeFlag);
443 zei = xmalloc (sizeof(*zei));
444 zei->updateHandle = updateHandle;
445 zei->updateFunc = updateFunc;
447 zei->curDatabaseInfo = NULL;
448 zei->records = records;
449 zei->nmem = nmem_create ();
453 zei->categoryList = nmem_malloc (zei->nmem,
454 sizeof(*zei->categoryList));
455 zei->categoryList->sysno = 0;
456 zei->categoryList->dirty = 0;
457 zei->categoryList->data1_categoryList = NULL;
460 tm = localtime (&our_time);
461 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
462 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
463 tm->tm_hour, tm->tm_min, tm->tm_sec);
465 zdip = &zei->databaseInfo;
466 trec = rec_get (records, 1); /* get "root" record */
468 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
469 if (trec) /* targetInfo already exists ... */
471 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
473 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
476 data1_pr_tree (zei->dh, zei->data1_target, stderr);
478 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
480 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
483 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
485 node_list = data1_search_tag (zei->dh, node_zebra->child,
487 for (np = node_list->child; np; np = np->next)
489 data1_node *node_name = NULL;
490 data1_node *node_id = NULL;
491 data1_node *node_aid = NULL;
493 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
495 for (np2 = np->child; np2; np2 = np2->next)
497 if (np2->which != DATA1N_tag)
499 if (!strcmp (np2->u.tag.tag, "name"))
500 node_name = np2->child;
501 else if (!strcmp (np2->u.tag.tag, "id"))
502 node_id = np2->child;
503 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
504 node_aid = np2->child;
506 assert (node_id && node_name && node_aid);
508 *zdip = nmem_malloc (zei->nmem, sizeof(**zdip));
510 (*zdip)->readFlag = 1;
512 (*zdip)->data1_database = NULL;
513 (*zdip)->recordCount = 0;
514 (*zdip)->recordBytes = 0;
515 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
517 (*zdip)->databaseName = nmem_malloc (zei->nmem,
518 1+node_name->u.data.len);
519 memcpy ((*zdip)->databaseName, node_name->u.data.data,
520 node_name->u.data.len);
521 (*zdip)->databaseName[node_name->u.data.len] = '\0';
522 (*zdip)->sysno = atoi_n (node_id->u.data.data,
523 node_id->u.data.len);
524 (*zdip)->attributeDetails =
525 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
526 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
527 node_aid->u.data.len);
528 (*zdip)->attributeDetails->readFlag = 1;
529 (*zdip)->attributeDetails->dirty = 0;
530 (*zdip)->attributeDetails->SUInfo = NULL;
532 zdip = &(*zdip)->next;
534 np = data1_search_tag (zei->dh, node_zebra->child,
537 assert (np && np->which == DATA1N_data);
538 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
540 np = data1_search_tag (zei->dh, node_zebra->child,
543 assert (np && np->which == DATA1N_data);
544 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
548 else /* create initial targetInfo */
550 data1_node *node_tgtinfo;
560 data1_read_sgml (zei->dh, zei->nmem,
561 "<explain><targetInfo>TargetInfo\n"
563 "<namedResultSets>1</>\n"
564 "<multipleDBSearch>1</>\n"
565 "<nicknames><name>Zebra</></>\n"
568 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
570 assert (node_tgtinfo);
572 zebraExplain_initCommonInfo (zei, node_tgtinfo);
573 zebraExplain_initAccessInfo (zei, node_tgtinfo);
575 /* write now because we want to be sure about the sysno */
576 trec = rec_new (records);
577 trec->info[recInfo_fileType] =
578 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
579 trec->info[recInfo_databaseName] =
580 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
582 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
583 trec->info[recInfo_storeData] = xmalloc (sgml_len);
584 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
585 trec->size[recInfo_storeData] = sgml_len;
587 rec_put (records, &trec);
591 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
593 if (!zei->categoryList->dirty)
595 struct zebraCategoryListInfo *zcl = zei->categoryList;
599 zcl->data1_categoryList =
600 data1_read_sgml (zei->dh, zei->nmem,
601 "<explain><categoryList>CategoryList\n"
603 node_cl = data1_search_tag (zei->dh,
604 zcl->data1_categoryList->child,
607 zebraExplain_initCommonInfo (zei, node_cl);
613 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
614 zebAttributeDetails zad)
617 struct zebSUInfoB **zsuip = &zad->SUInfo;
618 data1_node *node_adinfo, *node_zebra, *node_list, *np;
621 rec = rec_get (zei->records, zad->sysno);
623 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
625 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
627 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
629 node_list = data1_search_tag (zei->dh, node_zebra->child,
631 for (np = node_list->child; np; np = np->next)
633 data1_node *node_set = NULL;
634 data1_node *node_use = NULL;
635 data1_node *node_ordinal = NULL;
640 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
642 for (np2 = np->child; np2; np2 = np2->next)
644 if (np2->which != DATA1N_tag || !np2->child ||
645 np2->child->which != DATA1N_data)
647 if (!strcmp (np2->u.tag.tag, "set"))
648 node_set = np2->child;
649 else if (!strcmp (np2->u.tag.tag, "use"))
650 node_use = np2->child;
651 else if (!strcmp (np2->u.tag.tag, "ordinal"))
652 node_ordinal = np2->child;
654 assert (node_set && node_use && node_ordinal);
656 oid_str_len = node_set->u.data.len;
657 if (oid_str_len >= sizeof(oid_str))
658 oid_str_len = sizeof(oid_str)-1;
659 memcpy (oid_str, node_set->u.data.data, oid_str_len);
660 oid_str[oid_str_len] = '\0';
662 *zsuip = nmem_malloc (zei->nmem, sizeof(**zsuip));
663 (*zsuip)->info.set = oid_getvalbyname (oid_str);
665 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
666 node_use->u.data.len);
667 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
668 node_ordinal->u.data.len);
669 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
670 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
671 zsuip = &(*zsuip)->next;
678 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
679 struct zebDatabaseInfoB *zdi)
682 data1_node *node_dbinfo, *node_zebra, *np;
685 rec = rec_get (zei->records, zdi->sysno);
687 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
689 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
691 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
693 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
695 np = data1_search_tag (zei->dh, node_dbinfo->child,
697 if (np && np->child && np->child->which == DATA1N_data)
698 zdi->recordBytes = atoi_n (np->child->u.data.data,
699 np->child->u.data.len);
700 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
702 (np = data1_search_tag (zei->dh, np->child,
703 "recordCountActual")) &&
704 np->child->which == DATA1N_data)
706 zdi->recordCount = atoi_n (np->child->u.data.data,
707 np->child->u.data.len);
713 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
715 struct zebDatabaseInfoB *zdi;
718 if (zei->curDatabaseInfo &&
719 !strcmp (zei->curDatabaseInfo->databaseName, database))
721 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
723 if (!strcmp (zdi->databaseName, database))
729 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
734 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
736 zebraExplain_readDatabase (zei, zdi);
738 if (zdi->attributeDetails->readFlag)
741 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
743 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
745 zei->curDatabaseInfo = zdi;
749 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
751 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
753 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
754 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
755 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
758 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
760 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
762 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
765 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
767 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
768 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
769 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
772 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
773 zebAccessInfo accessInfo)
775 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
781 if ((p = accessInfo->attributeSetIds))
783 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
784 for (; p; p = p->next)
785 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
787 if ((p = accessInfo->schemas))
789 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
790 for (; p; p = p->next)
791 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
795 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
796 int explain_database)
798 struct zebDatabaseInfoB *zdi;
799 data1_node *node_dbinfo, *node_adinfo;
802 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
805 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
807 if (!strcmp (zdi->databaseName, database))
812 /* it's new really. make it */
813 zdi = nmem_malloc (zei->nmem, sizeof(*zdi));
814 zdi->next = zei->databaseInfo;
815 zei->databaseInfo = zdi;
817 zdi->recordCount = 0;
818 zdi->recordBytes = 0;
820 zdi->databaseName = nmem_strdup (zei->nmem, database);
822 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
827 zdi->data1_database =
828 data1_read_sgml (zei->dh, zei->nmem,
829 "<explain><databaseInfo>DatabaseInfo\n"
832 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
834 assert (node_dbinfo);
836 zebraExplain_initCommonInfo (zei, node_dbinfo);
837 zebraExplain_initAccessInfo (zei, node_dbinfo);
839 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
840 database, zei->nmem);
842 if (explain_database)
843 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
846 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
849 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
853 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
857 zei->curDatabaseInfo = zdi;
859 zdi->attributeDetails =
860 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
861 zdi->attributeDetails->readFlag = 0;
862 zdi->attributeDetails->sysno = 0;
863 zdi->attributeDetails->dirty = 1;
864 zdi->attributeDetails->SUInfo = NULL;
865 zdi->attributeDetails->data1_tree =
866 data1_read_sgml (zei->dh, zei->nmem,
867 "<explain><attributeDetails>AttributeDetails\n"
871 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
873 assert (node_adinfo);
875 zebraExplain_initCommonInfo (zei, node_adinfo);
880 static void writeAttributeValueDetails (ZebraExplainInfo zei,
881 zebAttributeDetails zad,
882 data1_node *node_atvs, data1_attset *attset)
885 struct zebSUInfoB *zsui;
886 int set_ordinal = attset->reference;
887 data1_attset_child *c;
889 for (c = attset->children; c; c = c->next)
890 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
891 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
893 data1_node *node_attvalue, *node_value;
894 if (set_ordinal != zsui->info.set)
896 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
898 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
900 data1_add_tagdata_int (zei->dh, node_value, "numeric",
901 zsui->info.use, zei->nmem);
905 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
906 struct zebraCategoryListInfo *zcl,
913 data1_node *node_ci, *node_categoryList;
915 static char *category[] = {
927 node_categoryList = zcl->data1_categoryList;
930 logf (LOG_LOG, "zebraExplain_writeCategoryList");
933 drec = createRecord (zei->records, &sysno);
935 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
938 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
941 for (i = 0; category[i]; i++)
943 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
944 "category", zei->nmem);
946 data1_add_tagdata_text (zei->dh, node_cat, "name",
947 category[i], zei->nmem);
949 /* extract *searchable* keys from it. We do this here, because
950 record count, etc. is affected */
952 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
954 /* convert to "SGML" and write it */
956 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
958 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList,
960 drec->info[recInfo_storeData] = xmalloc (sgml_len);
961 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
962 drec->size[recInfo_storeData] = sgml_len;
964 rec_put (zei->records, &drec);
967 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
968 zebAttributeDetails zad,
969 const char *databaseName,
975 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
976 struct zebSUInfoB *zsui;
984 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
987 drec = createRecord (zei->records, &zad->sysno);
988 assert (zad->data1_tree);
989 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
991 zebraExplain_updateCommonInfo (zei, node_adinfo);
993 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
994 databaseName, zei->nmem);
996 /* extract *searchable* keys from it. We do this here, because
997 record count, etc. is affected */
999 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1001 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
1002 "attributesBySet", zei->nmem);
1006 data1_node *node_asd;
1007 data1_attset *attset;
1008 int set_ordinal = -1;
1009 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1011 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1012 && zsui->info.set > set_min)
1013 set_ordinal = zsui->info.set;
1015 if (set_ordinal < 0)
1017 set_min = set_ordinal;
1018 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1019 "attributeSetDetails", zei->nmem);
1021 attset = data1_attset_search_id (zei->dh, set_ordinal);
1024 zebraExplain_loadAttsets (zei->dh, zei->res);
1025 attset = data1_attset_search_id (zei->dh, set_ordinal);
1032 oe.proto = PROTO_Z3950;
1033 oe.oclass = CLASS_ATTSET;
1034 oe.value = set_ordinal;
1036 if (oid_ent_to_oid (&oe, oid))
1038 data1_node *node_abt, *node_atd, *node_atvs;
1039 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1042 node_abt = data1_add_tag (zei->dh, node_asd,
1043 "attributesByType", zei->nmem);
1044 node_atd = data1_add_tag (zei->dh, node_abt,
1045 "attributeTypeDetails", zei->nmem);
1046 data1_add_tagdata_int (zei->dh, node_atd,
1047 "type", 1, zei->nmem);
1048 node_atvs = data1_add_tag (zei->dh, node_atd,
1049 "attributeValues", zei->nmem);
1050 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1054 /* zebra info (private) */
1055 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1056 "zebraInfo", zei->nmem);
1057 node_list = data1_make_tag (zei->dh, node_zebra,
1058 "attrlist", zei->nmem);
1059 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1061 struct oident oident;
1063 data1_node *node_attr;
1065 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1067 oident.proto = PROTO_Z3950;
1068 oident.oclass = CLASS_ATTSET;
1069 oident.value = zsui->info.set;
1070 oid_ent_to_oid (&oident, oid);
1072 data1_add_tagdata_text (zei->dh, node_attr, "set",
1073 oident.desc, zei->nmem);
1074 data1_add_tagdata_int (zei->dh, node_attr, "use",
1075 zsui->info.use, zei->nmem);
1076 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1077 zsui->info.ordinal, zei->nmem);
1079 /* convert to "SGML" and write it */
1081 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1083 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1085 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1086 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1087 drec->size[recInfo_storeData] = sgml_len;
1089 rec_put (zei->records, &drec);
1092 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1093 struct zebDatabaseInfoB *zdi,
1099 data1_node *node_dbinfo, *node_count, *node_zebra;
1106 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1108 drec = createRecord (zei->records, &zdi->sysno);
1109 assert (zdi->data1_database);
1110 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1113 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1114 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1116 /* extract *searchable* keys from it. We do this here, because
1117 record count, etc. is affected */
1119 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1121 node_count = data1_make_tag (zei->dh, node_dbinfo,
1122 "recordCount", zei->nmem);
1123 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1124 zdi->recordCount, zei->nmem);
1126 /* zebra info (private) */
1127 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1128 "zebraInfo", zei->nmem);
1129 data1_add_tagdata_int (zei->dh, node_zebra,
1130 "recordBytes", zdi->recordBytes, zei->nmem);
1131 /* convert to "SGML" and write it */
1133 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1135 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1137 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1138 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1139 drec->size[recInfo_storeData] = sgml_len;
1141 rec_put (zei->records, &drec);
1144 static void writeAttributeValues (ZebraExplainInfo zei,
1145 data1_node *node_values,
1146 data1_attset *attset)
1149 data1_attset_child *c;
1154 for (c = attset->children; c; c = c->next)
1155 writeAttributeValues (zei, node_values, c->child);
1156 for (atts = attset->atts; atts; atts = atts->next)
1158 data1_node *node_value;
1160 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1162 data1_add_tagdata_text (zei->dh, node_value, "name",
1163 atts->name, zei->nmem);
1164 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1165 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1166 atts->value, zei->nmem);
1171 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1178 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1179 data1_node *node_values;
1180 struct oident *entp;
1181 struct data1_attset *attset = NULL;
1183 if ((entp = oid_getentbyoid (o->oid)))
1184 attset = data1_attset_search_id (zei->dh, entp->value);
1187 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1188 attset ? attset->name : "<unknown>");
1191 drec = createRecord (zei->records, &o->sysno);
1193 data1_read_sgml (zei->dh, zei->nmem,
1194 "<explain><attributeSetInfo>AttributeSetInfo\n"
1197 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1198 "attributeSetInfo");
1200 zebraExplain_initCommonInfo (zei, node_attinfo);
1201 zebraExplain_updateCommonInfo (zei, node_attinfo);
1203 data1_add_tagdata_oid (zei->dh, node_attinfo,
1204 "oid", o->oid, zei->nmem);
1205 if (attset && attset->name)
1206 data1_add_tagdata_text (zei->dh, node_attinfo,
1207 "name", attset->name, zei->nmem);
1209 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1210 "attributes", zei->nmem);
1211 node_atttype = data1_make_tag (zei->dh, node_attributes,
1212 "attributeType", zei->nmem);
1213 data1_add_tagdata_text (zei->dh, node_atttype,
1214 "name", "Use", zei->nmem);
1215 data1_add_tagdata_text (zei->dh, node_atttype,
1216 "description", "Use Attribute", zei->nmem);
1217 data1_add_tagdata_int (zei->dh, node_atttype,
1218 "type", 1, zei->nmem);
1219 node_values = data1_add_tag (zei->dh, node_atttype,
1220 "attributeValues", zei->nmem);
1222 writeAttributeValues (zei, node_values, attset);
1224 /* extract *searchable* keys from it. We do this here, because
1225 record count, etc. is affected */
1227 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1228 /* convert to "SGML" and write it */
1230 data1_pr_tree (zei->dh, node_root, stderr);
1232 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1233 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1234 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1235 drec->size[recInfo_storeData] = sgml_len;
1237 rec_put (zei->records, &drec);
1240 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1242 struct zebDatabaseInfoB *zdi;
1243 data1_node *node_tgtinfo, *node_list, *node_zebra;
1252 trec = rec_get (zei->records, 1);
1253 xfree (trec->info[recInfo_storeData]);
1255 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1257 assert (node_tgtinfo);
1259 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1260 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1262 /* convert to "SGML" and write it */
1264 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1266 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1267 "zebraInfo", zei->nmem);
1268 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1269 ZEBRAVER, zei->nmem);
1270 node_list = data1_add_tag (zei->dh, node_zebra,
1271 "databaseList", zei->nmem);
1272 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1274 data1_node *node_db;
1275 node_db = data1_add_tag (zei->dh, node_list,
1276 "database", zei->nmem);
1277 data1_add_tagdata_text (zei->dh, node_db, "name",
1278 zdi->databaseName, zei->nmem);
1279 data1_add_tagdata_int (zei->dh, node_db, "id",
1280 zdi->sysno, zei->nmem);
1281 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1282 zdi->attributeDetails->sysno, zei->nmem);
1284 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1285 zei->ordinalSU, zei->nmem);
1287 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1288 zei->runNumber, zei->nmem);
1291 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1293 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1295 trec->info[recInfo_storeData] = xmalloc (sgml_len);
1296 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1297 trec->size[recInfo_storeData] = sgml_len;
1299 rec_put (zei->records, &trec);
1302 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1304 struct zebSUInfoB *zsui;
1306 assert (zei->curDatabaseInfo);
1307 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1308 zsui; zsui=zsui->next)
1309 if (zsui->info.use == use && zsui->info.set == set)
1310 return zsui->info.ordinal;
1314 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1315 zebAccessObject *op,
1320 for (ao = *op; ao; ao = ao->next)
1321 if (!oid_oidcmp (oid, ao->oid))
1325 ao = nmem_malloc (zei->nmem, sizeof(*ao));
1328 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1335 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1340 oe.proto = PROTO_Z3950;
1341 oe.oclass = CLASS_ATTSET;
1344 if (oid_ent_to_oid (&oe, oid))
1346 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1347 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1348 accessInfo->attributeSetIds, oid);
1352 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1354 struct zebSUInfoB *zsui;
1356 assert (zei->curDatabaseInfo);
1357 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1358 zsui; zsui=zsui->next)
1359 if (zsui->info.use == use && zsui->info.set == set)
1361 zebraExplain_addAttributeSet (zei, set);
1362 zsui = nmem_malloc (zei->nmem, sizeof(*zsui));
1363 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1364 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1365 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1367 zsui->info.set = set;
1368 zsui->info.use = use;
1369 zsui->info.ordinal = (zei->ordinalSU)++;
1370 return zsui->info.ordinal;
1373 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1375 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1376 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1377 accessInfo->schemas, oid);
1380 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1382 assert (zei->curDatabaseInfo);
1386 zei->curDatabaseInfo->recordBytes += adjust_num;
1387 zei->curDatabaseInfo->dirty = 1;
1391 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1393 assert (zei->curDatabaseInfo);
1397 zei->curDatabaseInfo->recordCount += adjust_num;
1398 zei->curDatabaseInfo->dirty = 1;
1402 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1406 return zei->runNumber += adjust_num;
1409 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1411 RecordAttr *recordAttr;
1413 if (rec->info[recInfo_attr])
1414 return (RecordAttr *) rec->info[recInfo_attr];
1415 recordAttr = xmalloc (sizeof(*recordAttr));
1416 rec->info[recInfo_attr] = (char *) recordAttr;
1417 rec->size[recInfo_attr] = sizeof(*recordAttr);
1419 recordAttr->recordSize = 0;
1420 recordAttr->recordOffset = 0;
1421 recordAttr->runNumber = zei->runNumber;
1425 static void att_loadset(void *p, const char *n, const char *name)
1427 data1_handle dh = p;
1428 if (!data1_get_attset (dh, name))
1429 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1432 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1434 res_trav(res, "attset", dh, att_loadset);
1438 zebraExplain_addSU adds to AttributeDetails for a database and
1439 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1440 exist for the database.
1442 If the database doesn't exist globally (in TargetInfo) an
1443 AttributeSetInfo must be added (globally).