2 * Copyright (C) 1994-1999, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.17 1999-07-14 10:53:51 adam
8 * Updated various routines to handle missing explain schema.
10 * Revision 1.16 1999/05/26 07:49:13 adam
13 * Revision 1.15 1999/01/25 13:47:54 adam
16 * Revision 1.14 1998/11/04 16:31:32 adam
17 * Fixed bug regarding recordBytes in databaseInfo.
19 * Revision 1.13 1998/11/03 10:17:09 adam
20 * Fixed bug regarding creation of some data1 nodes for Explain records.
22 * Revision 1.12 1998/10/13 20:37:11 adam
23 * Changed the way attribute sets are saved in Explain database to
24 * reflect "dynamic" OIDs.
26 * Revision 1.11 1998/06/09 12:16:48 adam
27 * Implemented auto-generation of CategoryList records.
29 * Revision 1.10 1998/06/08 14:43:15 adam
30 * Added suport for EXPLAIN Proxy servers - added settings databasePath
31 * and explainDatabase to facilitate this. Increased maximum number
32 * of databases and attributes in one register.
34 * Revision 1.9 1998/06/02 12:10:27 adam
35 * Fixed bug related to attributeDetails.
37 * Revision 1.8 1998/05/20 10:12:20 adam
38 * Implemented automatic EXPLAIN database maintenance.
39 * Modified Zebra to work with ASN.1 compiled version of YAZ.
41 * Revision 1.7 1998/03/05 08:45:13 adam
42 * New result set model and modular ranking system. Moved towards
43 * descent server API. System information stored as "SGML" records.
45 * Revision 1.6 1998/02/17 10:29:27 adam
46 * Moved towards 'automatic' EXPLAIN database.
48 * Revision 1.5 1997/10/27 14:33:05 adam
49 * Moved towards generic character mapping depending on "structure"
50 * field in abstract syntax file. Fixed a few memory leaks. Fixed
51 * bug with negative integers when doing searches with relational
54 * Revision 1.4 1997/09/25 14:57:08 adam
57 * Revision 1.3 1996/05/22 08:21:59 adam
58 * Added public ZebDatabaseInfo structure.
60 * Revision 1.2 1996/05/14 06:16:41 adam
61 * Compact use/set bytes used in search service.
63 * Revision 1.1 1996/05/13 14:23:07 adam
64 * Work on compaction of set/use bytes in dictionary.
85 struct zebSUInfo info;
86 struct zebSUInfoB *next;
89 typedef struct zebAccessObjectB *zebAccessObject;
90 struct zebAccessObjectB {
97 typedef struct zebAccessInfoB *zebAccessInfo;
98 struct zebAccessInfoB {
99 zebAccessObject attributeSetIds;
100 zebAccessObject schemas;
104 struct zebSUInfoB *SUInfo;
108 data1_node *data1_tree;
109 } *zebAttributeDetails;
111 struct zebDatabaseInfoB {
112 zebAttributeDetails attributeDetails;
114 data1_node *data1_database;
115 int recordCount; /* records in db */
116 int recordBytes; /* size of records */
117 int sysno; /* sysno of database info */
118 int readFlag; /* 1: read is needed when referenced; 0 if not */
119 int dirty; /* 1: database is dirty: write is needed */
120 struct zebDatabaseInfoB *next;
121 zebAccessInfo accessInfo;
124 struct zebraExplainAttset {
127 struct zebraExplainAttset *next;
130 struct zebraCategoryListInfo {
133 data1_node *data1_categoryList;
136 struct zebraExplainInfo {
143 struct zebraExplainAttset *attsets;
145 data1_node *data1_target;
146 struct zebraCategoryListInfo *categoryList;
147 struct zebDatabaseInfoB *databaseInfo;
148 struct zebDatabaseInfoB *curDatabaseInfo;
149 zebAccessInfo accessInfo;
150 char date[15]; /* YYYY MMDD HH MM SS */
151 int (*updateFunc)(void *handle, Record drec, data1_node *n);
155 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
156 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
158 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
160 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
163 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
166 logf (LOG_DEBUG, "data1_search_tag %s", tag);
167 for (; n; n = n->next)
168 if (n->which == DATA1N_tag && n->u.tag.tag &&
169 !yaz_matchstr (tag, n->u.tag.tag))
171 logf (LOG_DEBUG, " found");
174 logf (LOG_DEBUG, " not found");
178 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
179 const char *tag, NMEM nmem)
181 data1_node *partag = get_parent_tag(dh, at);
182 data1_node *res = data1_mk_node (dh, nmem);
183 data1_element *e = NULL;
186 res->which = DATA1N_tag;
187 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
188 res->u.tag.node_selected = 0;
189 res->u.tag.make_variantlist = 0;
190 res->u.tag.no_data_requested = 0;
191 res->u.tag.get_bytes = -1;
194 e = partag->u.tag.element;
196 data1_getelementbytagname (dh, at->root->u.root.absyn,
198 res->root = at->root;
203 assert (at->last_child);
204 at->last_child->next = res;
206 at->last_child = res;
210 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
211 const char *tag, NMEM nmem)
213 data1_node *node = data1_search_tag (dh, at->child, tag);
215 node = data1_add_tag (dh, at, tag, nmem);
217 node->child = node->last_child = NULL;
221 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
222 const char *tag, int num,
225 data1_node *node_data;
227 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
230 node_data->u.data.what = DATA1I_num;
231 node_data->u.data.data = node_data->lbuf;
232 sprintf (node_data->u.data.data, "%d", num);
233 node_data->u.data.len = strlen (node_data->u.data.data);
237 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
238 const char *tag, Odr_oid *oid,
241 data1_node *node_data;
242 char str[128], *p = str;
245 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
249 for (ii = oid; *ii >= 0; ii++)
253 sprintf (p, "%d", *ii);
256 node_data->u.data.what = DATA1I_oid;
257 node_data->u.data.len = strlen (str);
258 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
263 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
264 const char *tag, const char *str,
267 data1_node *node_data;
269 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
272 node_data->u.data.what = DATA1I_text;
273 node_data->u.data.len = strlen (str);
274 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
278 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
279 const char *tag, const char *str,
282 data1_node *node = data1_search_tag (dh, at->child, tag);
284 return data1_add_tagdata_text (dh, at, tag, str, nmem);
287 data1_node *node_data = node->child;
288 node_data->u.data.what = DATA1I_text;
289 node_data->u.data.len = strlen (str);
290 node_data->u.data.data = data1_insert_string (dh, node_data,
296 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
297 struct zebDatabaseInfoB *zdi,
299 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
300 zebAttributeDetails zad,
301 const char *databaseName,
303 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
304 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
307 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
308 struct zebraCategoryListInfo *zcl,
312 static Record createRecord (Records records, int *sysno)
317 rec = rec_get (records, *sysno);
318 xfree (rec->info[recInfo_storeData]);
322 rec = rec_new (records);
325 rec->info[recInfo_fileType] =
326 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
327 rec->info[recInfo_databaseName] =
328 rec_strdup ("IR-Explain-1",
329 &rec->size[recInfo_databaseName]);
334 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag,
335 int (*updateH)(Record drec, data1_node *n))
337 struct zebDatabaseInfoB *zdi;
339 logf (LOG_DEBUG, "zebraExplain_close wr=%d", writeFlag);
345 /* write each database info record */
346 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
348 zebraExplain_writeDatabase (zei, zdi, 1);
349 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
350 zdi->databaseName, 1);
352 zebraExplain_writeTarget (zei, 1);
353 zebraExplain_writeCategoryList (zei,
356 assert (zei->accessInfo);
357 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
359 zebraExplain_writeAttributeSet (zei, o, 1);
360 for (o = zei->accessInfo->schemas; o; o = o->next)
363 /* zebraExplain_writeSchema (zei, o, 1); */
366 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
368 zebraExplain_writeDatabase (zei, zdi, 0);
369 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
370 zdi->databaseName, 0);
372 zebraExplain_writeTarget (zei, 0);
375 nmem_destroy (zei->nmem);
378 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
383 for (np = n->child; np; np = np->next)
390 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
392 len = np->child->u.data.len;
395 memcpy (str, np->child->u.data.data, len);
398 oid = odr_getoidbystr_nmem (zei->nmem, str);
400 for (ao = *op; ao; ao = ao->next)
401 if (!oid_oidcmp (oid, ao->oid))
408 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
418 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
419 zebAccessInfo *accessInfo)
425 *accessInfo = (zebAccessInfo)
426 nmem_malloc (zei->nmem, sizeof(**accessInfo));
427 (*accessInfo)->attributeSetIds = NULL;
428 (*accessInfo)->schemas = NULL;
432 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
434 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
435 zebraExplain_mergeOids (zei, np,
436 &(*accessInfo)->attributeSetIds);
437 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
438 zebraExplain_mergeOids (zei, np,
439 &(*accessInfo)->schemas);
443 ZebraExplainInfo zebraExplain_open (
444 Records records, data1_handle dh,
448 int (*updateFunc)(void *handle, Record drec, data1_node *n))
451 ZebraExplainInfo zei;
452 struct zebDatabaseInfoB **zdip;
455 NMEM nmem = nmem_create ();
457 logf (LOG_DEBUG, "zebraExplain_open wr=%d", writeFlag);
458 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
459 zei->updateHandle = updateHandle;
460 zei->updateFunc = updateFunc;
462 zei->curDatabaseInfo = NULL;
463 zei->records = records;
468 zei->categoryList = (struct zebraCategoryListInfo *)
469 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
470 zei->categoryList->sysno = 0;
471 zei->categoryList->dirty = 0;
472 zei->categoryList->data1_categoryList = NULL;
475 tm = localtime (&our_time);
476 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
477 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
478 tm->tm_hour, tm->tm_min, tm->tm_sec);
480 zdip = &zei->databaseInfo;
481 trec = rec_get (records, 1); /* get "root" record */
483 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
484 if (trec) /* targetInfo already exists ... */
486 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
488 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
489 if (!zei->data1_target)
492 nmem_destroy(zei->nmem);
496 data1_pr_tree (zei->dh, zei->data1_target, stderr);
498 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
500 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
503 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
505 node_list = data1_search_tag (zei->dh, node_zebra->child,
507 for (np = node_list->child; np; np = np->next)
509 data1_node *node_name = NULL;
510 data1_node *node_id = NULL;
511 data1_node *node_aid = NULL;
513 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
515 for (np2 = np->child; np2; np2 = np2->next)
517 if (np2->which != DATA1N_tag)
519 if (!strcmp (np2->u.tag.tag, "name"))
520 node_name = np2->child;
521 else if (!strcmp (np2->u.tag.tag, "id"))
522 node_id = np2->child;
523 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
524 node_aid = np2->child;
526 assert (node_id && node_name && node_aid);
528 *zdip = (struct zebDatabaseInfoB *)
529 nmem_malloc (zei->nmem, sizeof(**zdip));
530 (*zdip)->readFlag = 1;
532 (*zdip)->data1_database = NULL;
533 (*zdip)->recordCount = 0;
534 (*zdip)->recordBytes = 0;
535 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
537 (*zdip)->databaseName = (char *)
538 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
539 memcpy ((*zdip)->databaseName, node_name->u.data.data,
540 node_name->u.data.len);
541 (*zdip)->databaseName[node_name->u.data.len] = '\0';
542 (*zdip)->sysno = atoi_n (node_id->u.data.data,
543 node_id->u.data.len);
544 (*zdip)->attributeDetails = (zebAttributeDetails)
545 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
546 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
547 node_aid->u.data.len);
548 (*zdip)->attributeDetails->readFlag = 1;
549 (*zdip)->attributeDetails->dirty = 0;
550 (*zdip)->attributeDetails->SUInfo = NULL;
552 zdip = &(*zdip)->next;
554 np = data1_search_tag (zei->dh, node_zebra->child,
557 assert (np && np->which == DATA1N_data);
558 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
560 np = data1_search_tag (zei->dh, node_zebra->child,
563 assert (np && np->which == DATA1N_data);
564 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
568 else /* create initial targetInfo */
570 data1_node *node_tgtinfo;
581 data1_read_sgml (zei->dh, zei->nmem,
582 "<explain><targetInfo>TargetInfo\n"
584 "<namedResultSets>1</>\n"
585 "<multipleDBSearch>1</>\n"
586 "<nicknames><name>Zebra</></>\n"
589 if (!zei->data1_target)
591 nmem_destroy (zei->nmem);
594 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
596 assert (node_tgtinfo);
598 zebraExplain_initCommonInfo (zei, node_tgtinfo);
599 zebraExplain_initAccessInfo (zei, node_tgtinfo);
601 /* write now because we want to be sure about the sysno */
602 trec = rec_new (records);
603 trec->info[recInfo_fileType] =
604 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
605 trec->info[recInfo_databaseName] =
606 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
608 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
609 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
610 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
611 trec->size[recInfo_storeData] = sgml_len;
613 rec_put (records, &trec);
617 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
619 if (!zei->categoryList->dirty)
621 struct zebraCategoryListInfo *zcl = zei->categoryList;
625 zcl->data1_categoryList =
626 data1_read_sgml (zei->dh, zei->nmem,
627 "<explain><categoryList>CategoryList\n"
630 if (zcl->data1_categoryList)
632 assert (zcl->data1_categoryList->child);
633 node_cl = data1_search_tag (zei->dh,
634 zcl->data1_categoryList->child,
637 zebraExplain_initCommonInfo (zei, node_cl);
644 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
645 zebAttributeDetails zad)
648 struct zebSUInfoB **zsuip = &zad->SUInfo;
649 data1_node *node_adinfo, *node_zebra, *node_list, *np;
652 rec = rec_get (zei->records, zad->sysno);
654 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
656 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
658 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
660 node_list = data1_search_tag (zei->dh, node_zebra->child,
662 for (np = node_list->child; np; np = np->next)
664 data1_node *node_set = NULL;
665 data1_node *node_use = NULL;
666 data1_node *node_ordinal = NULL;
671 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
673 for (np2 = np->child; np2; np2 = np2->next)
675 if (np2->which != DATA1N_tag || !np2->child ||
676 np2->child->which != DATA1N_data)
678 if (!strcmp (np2->u.tag.tag, "set"))
679 node_set = np2->child;
680 else if (!strcmp (np2->u.tag.tag, "use"))
681 node_use = np2->child;
682 else if (!strcmp (np2->u.tag.tag, "ordinal"))
683 node_ordinal = np2->child;
685 assert (node_set && node_use && node_ordinal);
687 oid_str_len = node_set->u.data.len;
688 if (oid_str_len >= (int) sizeof(oid_str))
689 oid_str_len = sizeof(oid_str)-1;
690 memcpy (oid_str, node_set->u.data.data, oid_str_len);
691 oid_str[oid_str_len] = '\0';
693 *zsuip = (struct zebSUInfoB *)
694 nmem_malloc (zei->nmem, sizeof(**zsuip));
695 (*zsuip)->info.set = oid_getvalbyname (oid_str);
697 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
698 node_use->u.data.len);
699 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
700 node_ordinal->u.data.len);
701 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
702 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
703 zsuip = &(*zsuip)->next;
710 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
711 struct zebDatabaseInfoB *zdi)
714 data1_node *node_dbinfo, *node_zebra, *np;
717 rec = rec_get (zei->records, zdi->sysno);
719 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
721 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
723 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
725 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
728 && (np = data1_search_tag (zei->dh, node_zebra->child,
730 && np->child && np->child->which == DATA1N_data)
731 zdi->recordBytes = atoi_n (np->child->u.data.data,
732 np->child->u.data.len);
733 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
735 (np = data1_search_tag (zei->dh, np->child,
736 "recordCountActual")) &&
737 np->child->which == DATA1N_data)
739 zdi->recordCount = atoi_n (np->child->u.data.data,
740 np->child->u.data.len);
746 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
748 struct zebDatabaseInfoB *zdi;
751 if (zei->curDatabaseInfo &&
752 !strcmp (zei->curDatabaseInfo->databaseName, database))
754 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
756 if (!strcmp (zdi->databaseName, database))
762 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
767 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
769 zebraExplain_readDatabase (zei, zdi);
771 if (zdi->attributeDetails->readFlag)
774 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
776 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
778 zei->curDatabaseInfo = zdi;
782 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
784 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
786 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
787 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
788 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
791 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
793 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
795 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
798 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
800 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
801 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
802 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
805 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
806 zebAccessInfo accessInfo)
808 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
814 if ((p = accessInfo->attributeSetIds))
816 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
817 for (; p; p = p->next)
818 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
820 if ((p = accessInfo->schemas))
822 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
823 for (; p; p = p->next)
824 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
828 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
829 int explain_database)
831 struct zebDatabaseInfoB *zdi;
832 data1_node *node_dbinfo, *node_adinfo;
835 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
838 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
840 if (!strcmp (zdi->databaseName, database))
845 /* it's new really. make it */
846 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
847 zdi->next = zei->databaseInfo;
848 zei->databaseInfo = zdi;
850 zdi->recordCount = 0;
851 zdi->recordBytes = 0;
853 zdi->databaseName = nmem_strdup (zei->nmem, database);
855 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
860 zdi->data1_database =
861 data1_read_sgml (zei->dh, zei->nmem,
862 "<explain><databaseInfo>DatabaseInfo\n"
864 if (!zdi->data1_database)
867 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
869 assert (node_dbinfo);
871 zebraExplain_initCommonInfo (zei, node_dbinfo);
872 zebraExplain_initAccessInfo (zei, node_dbinfo);
874 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
875 database, zei->nmem);
877 if (explain_database)
878 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
881 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
884 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
888 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
892 zei->curDatabaseInfo = zdi;
894 zdi->attributeDetails = (zebAttributeDetails)
895 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
896 zdi->attributeDetails->readFlag = 0;
897 zdi->attributeDetails->sysno = 0;
898 zdi->attributeDetails->dirty = 1;
899 zdi->attributeDetails->SUInfo = NULL;
900 zdi->attributeDetails->data1_tree =
901 data1_read_sgml (zei->dh, zei->nmem,
902 "<explain><attributeDetails>AttributeDetails\n"
906 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
908 assert (node_adinfo);
910 zebraExplain_initCommonInfo (zei, node_adinfo);
915 static void writeAttributeValueDetails (ZebraExplainInfo zei,
916 zebAttributeDetails zad,
917 data1_node *node_atvs, data1_attset *attset)
920 struct zebSUInfoB *zsui;
921 int set_ordinal = attset->reference;
922 data1_attset_child *c;
924 for (c = attset->children; c; c = c->next)
925 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
926 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
928 data1_node *node_attvalue, *node_value;
929 if (set_ordinal != zsui->info.set)
931 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
933 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
935 data1_add_tagdata_int (zei->dh, node_value, "numeric",
936 zsui->info.use, zei->nmem);
940 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
941 struct zebraCategoryListInfo *zcl,
948 data1_node *node_ci, *node_categoryList;
950 static char *category[] = {
962 node_categoryList = zcl->data1_categoryList;
965 logf (LOG_LOG, "zebraExplain_writeCategoryList");
968 drec = createRecord (zei->records, &sysno);
970 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
973 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
976 for (i = 0; category[i]; i++)
978 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
979 "category", zei->nmem);
981 data1_add_tagdata_text (zei->dh, node_cat, "name",
982 category[i], zei->nmem);
984 /* extract *searchable* keys from it. We do this here, because
985 record count, etc. is affected */
987 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
989 /* convert to "SGML" and write it */
991 data1_pr_tree (zei->dh, node_categoryList, stderr);
993 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
994 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
995 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
996 drec->size[recInfo_storeData] = sgml_len;
998 rec_put (zei->records, &drec);
1001 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1002 zebAttributeDetails zad,
1003 const char *databaseName,
1009 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
1010 struct zebSUInfoB *zsui;
1018 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
1021 drec = createRecord (zei->records, &zad->sysno);
1022 assert (zad->data1_tree);
1023 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
1024 "attributeDetails");
1025 zebraExplain_updateCommonInfo (zei, node_adinfo);
1027 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
1028 databaseName, zei->nmem);
1030 /* extract *searchable* keys from it. We do this here, because
1031 record count, etc. is affected */
1033 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1035 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
1036 "attributesBySet", zei->nmem);
1040 data1_node *node_asd;
1041 data1_attset *attset;
1042 int set_ordinal = -1;
1043 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1045 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1046 && zsui->info.set > set_min)
1047 set_ordinal = zsui->info.set;
1049 if (set_ordinal < 0)
1051 set_min = set_ordinal;
1052 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1053 "attributeSetDetails", zei->nmem);
1055 attset = data1_attset_search_id (zei->dh, set_ordinal);
1058 zebraExplain_loadAttsets (zei->dh, zei->res);
1059 attset = data1_attset_search_id (zei->dh, set_ordinal);
1066 oe.proto = PROTO_Z3950;
1067 oe.oclass = CLASS_ATTSET;
1068 oe.value = (enum oid_value) set_ordinal;
1070 if (oid_ent_to_oid (&oe, oid))
1072 data1_node *node_abt, *node_atd, *node_atvs;
1073 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1076 node_abt = data1_add_tag (zei->dh, node_asd,
1077 "attributesByType", zei->nmem);
1078 node_atd = data1_add_tag (zei->dh, node_abt,
1079 "attributeTypeDetails", zei->nmem);
1080 data1_add_tagdata_int (zei->dh, node_atd,
1081 "type", 1, zei->nmem);
1082 node_atvs = data1_add_tag (zei->dh, node_atd,
1083 "attributeValues", zei->nmem);
1084 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1088 /* zebra info (private) */
1089 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1090 "zebraInfo", zei->nmem);
1091 node_list = data1_make_tag (zei->dh, node_zebra,
1092 "attrlist", zei->nmem);
1093 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1095 struct oident oident;
1097 data1_node *node_attr;
1099 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1101 oident.proto = PROTO_Z3950;
1102 oident.oclass = CLASS_ATTSET;
1103 oident.value = (enum oid_value) zsui->info.set;
1104 oid_ent_to_oid (&oident, oid);
1106 data1_add_tagdata_text (zei->dh, node_attr, "set",
1107 oident.desc, zei->nmem);
1108 data1_add_tagdata_int (zei->dh, node_attr, "use",
1109 zsui->info.use, zei->nmem);
1110 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1111 zsui->info.ordinal, zei->nmem);
1113 /* convert to "SGML" and write it */
1115 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1117 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1119 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1120 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1121 drec->size[recInfo_storeData] = sgml_len;
1123 rec_put (zei->records, &drec);
1126 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1127 struct zebDatabaseInfoB *zdi,
1133 data1_node *node_dbinfo, *node_count, *node_zebra;
1140 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1142 drec = createRecord (zei->records, &zdi->sysno);
1143 assert (zdi->data1_database);
1144 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1147 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1148 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1150 /* extract *searchable* keys from it. We do this here, because
1151 record count, etc. is affected */
1153 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1155 node_count = data1_make_tag (zei->dh, node_dbinfo,
1156 "recordCount", zei->nmem);
1157 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1158 zdi->recordCount, zei->nmem);
1160 /* zebra info (private) */
1161 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1162 "zebraInfo", zei->nmem);
1163 data1_add_tagdata_int (zei->dh, node_zebra,
1164 "recordBytes", zdi->recordBytes, zei->nmem);
1165 /* convert to "SGML" and write it */
1167 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1169 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1171 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1172 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1173 drec->size[recInfo_storeData] = sgml_len;
1175 rec_put (zei->records, &drec);
1178 static void writeAttributeValues (ZebraExplainInfo zei,
1179 data1_node *node_values,
1180 data1_attset *attset)
1183 data1_attset_child *c;
1188 for (c = attset->children; c; c = c->next)
1189 writeAttributeValues (zei, node_values, c->child);
1190 for (atts = attset->atts; atts; atts = atts->next)
1192 data1_node *node_value;
1194 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1196 data1_add_tagdata_text (zei->dh, node_value, "name",
1197 atts->name, zei->nmem);
1198 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1199 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1200 atts->value, zei->nmem);
1205 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1212 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1213 data1_node *node_values;
1214 struct oident *entp;
1215 struct data1_attset *attset = NULL;
1217 if ((entp = oid_getentbyoid (o->oid)))
1218 attset = data1_attset_search_id (zei->dh, entp->value);
1221 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1222 attset ? attset->name : "<unknown>");
1225 drec = createRecord (zei->records, &o->sysno);
1227 data1_read_sgml (zei->dh, zei->nmem,
1228 "<explain><attributeSetInfo>AttributeSetInfo\n"
1231 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1232 "attributeSetInfo");
1234 zebraExplain_initCommonInfo (zei, node_attinfo);
1235 zebraExplain_updateCommonInfo (zei, node_attinfo);
1237 data1_add_tagdata_oid (zei->dh, node_attinfo,
1238 "oid", o->oid, zei->nmem);
1239 if (attset && attset->name)
1240 data1_add_tagdata_text (zei->dh, node_attinfo,
1241 "name", attset->name, zei->nmem);
1243 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1244 "attributes", zei->nmem);
1245 node_atttype = data1_make_tag (zei->dh, node_attributes,
1246 "attributeType", zei->nmem);
1247 data1_add_tagdata_text (zei->dh, node_atttype,
1248 "name", "Use", zei->nmem);
1249 data1_add_tagdata_text (zei->dh, node_atttype,
1250 "description", "Use Attribute", zei->nmem);
1251 data1_add_tagdata_int (zei->dh, node_atttype,
1252 "type", 1, zei->nmem);
1253 node_values = data1_add_tag (zei->dh, node_atttype,
1254 "attributeValues", zei->nmem);
1256 writeAttributeValues (zei, node_values, attset);
1258 /* extract *searchable* keys from it. We do this here, because
1259 record count, etc. is affected */
1261 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1262 /* convert to "SGML" and write it */
1264 data1_pr_tree (zei->dh, node_root, stderr);
1266 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1267 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1268 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1269 drec->size[recInfo_storeData] = sgml_len;
1271 rec_put (zei->records, &drec);
1274 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1276 struct zebDatabaseInfoB *zdi;
1277 data1_node *node_tgtinfo, *node_list, *node_zebra;
1286 trec = rec_get (zei->records, 1);
1287 xfree (trec->info[recInfo_storeData]);
1289 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1291 assert (node_tgtinfo);
1293 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1294 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1296 /* convert to "SGML" and write it */
1298 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1300 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1301 "zebraInfo", zei->nmem);
1302 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1303 ZEBRAVER, zei->nmem);
1304 node_list = data1_add_tag (zei->dh, node_zebra,
1305 "databaseList", zei->nmem);
1306 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1308 data1_node *node_db;
1309 node_db = data1_add_tag (zei->dh, node_list,
1310 "database", zei->nmem);
1311 data1_add_tagdata_text (zei->dh, node_db, "name",
1312 zdi->databaseName, zei->nmem);
1313 data1_add_tagdata_int (zei->dh, node_db, "id",
1314 zdi->sysno, zei->nmem);
1315 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1316 zdi->attributeDetails->sysno, zei->nmem);
1318 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1319 zei->ordinalSU, zei->nmem);
1321 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1322 zei->runNumber, zei->nmem);
1325 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1327 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1329 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1330 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1331 trec->size[recInfo_storeData] = sgml_len;
1333 rec_put (zei->records, &trec);
1336 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1338 struct zebSUInfoB *zsui;
1340 assert (zei->curDatabaseInfo);
1341 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1342 zsui; zsui=zsui->next)
1343 if (zsui->info.use == use && zsui->info.set == set)
1344 return zsui->info.ordinal;
1348 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1349 zebAccessObject *op,
1354 for (ao = *op; ao; ao = ao->next)
1355 if (!oid_oidcmp (oid, ao->oid))
1359 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1362 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1369 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1374 oe.proto = PROTO_Z3950;
1375 oe.oclass = CLASS_ATTSET;
1376 oe.value = (enum oid_value) set;
1378 if (oid_ent_to_oid (&oe, oid))
1380 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1381 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1382 accessInfo->attributeSetIds, oid);
1386 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1388 struct zebSUInfoB *zsui;
1390 assert (zei->curDatabaseInfo);
1391 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1392 zsui; zsui=zsui->next)
1393 if (zsui->info.use == use && zsui->info.set == set)
1395 zebraExplain_addAttributeSet (zei, set);
1396 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1397 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1398 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1399 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1401 zsui->info.set = set;
1402 zsui->info.use = use;
1403 zsui->info.ordinal = (zei->ordinalSU)++;
1404 return zsui->info.ordinal;
1407 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1409 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1410 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1411 accessInfo->schemas, oid);
1414 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1416 assert (zei->curDatabaseInfo);
1420 zei->curDatabaseInfo->recordBytes += adjust_num;
1421 zei->curDatabaseInfo->dirty = 1;
1425 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1427 assert (zei->curDatabaseInfo);
1431 zei->curDatabaseInfo->recordCount += adjust_num;
1432 zei->curDatabaseInfo->dirty = 1;
1436 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1440 return zei->runNumber += adjust_num;
1443 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1445 RecordAttr *recordAttr;
1447 if (rec->info[recInfo_attr])
1448 return (RecordAttr *) rec->info[recInfo_attr];
1449 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1450 rec->info[recInfo_attr] = (char *) recordAttr;
1451 rec->size[recInfo_attr] = sizeof(*recordAttr);
1453 recordAttr->recordSize = 0;
1454 recordAttr->recordOffset = 0;
1455 recordAttr->runNumber = zei->runNumber;
1459 static void att_loadset(void *p, const char *n, const char *name)
1461 data1_handle dh = (data1_handle) p;
1462 if (!data1_get_attset (dh, name))
1463 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1466 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1468 res_trav(res, "attset", dh, att_loadset);
1472 zebraExplain_addSU adds to AttributeDetails for a database and
1473 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1474 exist for the database.
1476 If the database doesn't exist globally (in TargetInfo) an
1477 AttributeSetInfo must be added (globally).