2 * Copyright (C) 1994-1998, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.12 1998-10-13 20:37:11 adam
8 * Changed the way attribute sets are saved in Explain database to
9 * reflect "dynamic" OIDs.
11 * Revision 1.11 1998/06/09 12:16:48 adam
12 * Implemented auto-generation of CategoryList records.
14 * Revision 1.10 1998/06/08 14:43:15 adam
15 * Added suport for EXPLAIN Proxy servers - added settings databasePath
16 * and explainDatabase to facilitate this. Increased maximum number
17 * of databases and attributes in one register.
19 * Revision 1.9 1998/06/02 12:10:27 adam
20 * Fixed bug related to attributeDetails.
22 * Revision 1.8 1998/05/20 10:12:20 adam
23 * Implemented automatic EXPLAIN database maintenance.
24 * Modified Zebra to work with ASN.1 compiled version of YAZ.
26 * Revision 1.7 1998/03/05 08:45:13 adam
27 * New result set model and modular ranking system. Moved towards
28 * descent server API. System information stored as "SGML" records.
30 * Revision 1.6 1998/02/17 10:29:27 adam
31 * Moved towards 'automatic' EXPLAIN database.
33 * Revision 1.5 1997/10/27 14:33:05 adam
34 * Moved towards generic character mapping depending on "structure"
35 * field in abstract syntax file. Fixed a few memory leaks. Fixed
36 * bug with negative integers when doing searches with relational
39 * Revision 1.4 1997/09/25 14:57:08 adam
42 * Revision 1.3 1996/05/22 08:21:59 adam
43 * Added public ZebDatabaseInfo structure.
45 * Revision 1.2 1996/05/14 06:16:41 adam
46 * Compact use/set bytes used in search service.
48 * Revision 1.1 1996/05/13 14:23:07 adam
49 * Work on compaction of set/use bytes in dictionary.
70 struct zebSUInfo info;
71 struct zebSUInfoB *next;
74 typedef struct zebAccessObjectB *zebAccessObject;
75 struct zebAccessObjectB {
82 typedef struct zebAccessInfoB *zebAccessInfo;
83 struct zebAccessInfoB {
84 zebAccessObject attributeSetIds;
85 zebAccessObject schemas;
89 struct zebSUInfoB *SUInfo;
93 data1_node *data1_tree;
94 } *zebAttributeDetails;
96 struct zebDatabaseInfoB {
97 zebAttributeDetails attributeDetails;
99 data1_node *data1_database;
100 int recordCount; /* records in db */
101 int recordBytes; /* size of records */
102 int sysno; /* sysno of database info */
103 int readFlag; /* 1: read is needed when referenced; 0 if not */
104 int dirty; /* 1: database is dirty: write is needed */
105 struct zebDatabaseInfoB *next;
106 zebAccessInfo accessInfo;
109 struct zebraExplainAttset {
112 struct zebraExplainAttset *next;
115 struct zebraCategoryListInfo {
118 data1_node *data1_categoryList;
121 struct zebraExplainInfo {
128 struct zebraExplainAttset *attsets;
130 data1_node *data1_target;
131 struct zebraCategoryListInfo *categoryList;
132 struct zebDatabaseInfoB *databaseInfo;
133 struct zebDatabaseInfoB *curDatabaseInfo;
134 zebAccessInfo accessInfo;
135 char date[15]; /* YYYY MMDD HH MM SS */
136 int (*updateFunc)(void *handle, Record drec, data1_node *n);
140 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
141 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
143 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
145 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
148 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
151 logf (LOG_DEBUG, "data1_search_tag %s", tag);
152 for (; n; n = n->next)
153 if (n->which == DATA1N_tag && n->u.tag.tag &&
154 !yaz_matchstr (tag, n->u.tag.tag))
156 logf (LOG_DEBUG, " found");
159 logf (LOG_DEBUG, " not found");
163 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
164 const char *tag, NMEM nmem)
166 data1_node *partag = get_parent_tag(dh, at);
167 data1_node *res = data1_mk_node (dh, nmem);
168 data1_element *e = NULL;
171 res->which = DATA1N_tag;
172 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
173 res->u.tag.node_selected = 0;
174 res->u.tag.make_variantlist = 0;
175 res->u.tag.no_data_requested = 0;
176 res->u.tag.get_bytes = -1;
179 e = partag->u.tag.element;
181 data1_getelementbytagname (dh, at->root->u.root.absyn,
183 res->root = at->root;
188 assert (at->last_child);
189 at->last_child->next = res;
191 at->last_child = res;
195 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
196 const char *tag, NMEM nmem)
198 data1_node *node = data1_search_tag (dh, at->child, tag);
200 node = data1_add_tag (dh, at, tag, nmem);
202 node->child = node->last_child = NULL;
206 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
207 const char *tag, int num,
210 data1_node *node_data;
212 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
215 node_data->u.data.what = DATA1I_num;
216 node_data->u.data.data = node_data->lbuf;
217 sprintf (node_data->u.data.data, "%d", num);
218 node_data->u.data.len = strlen (node_data->u.data.data);
222 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
223 const char *tag, Odr_oid *oid,
226 data1_node *node_data;
227 char str[128], *p = str;
230 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
234 for (ii = oid; *ii >= 0; ii++)
238 sprintf (p, "%d", *ii);
241 node_data->u.data.what = DATA1I_oid;
242 node_data->u.data.len = strlen (str);
243 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
248 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
249 const char *tag, const char *str,
252 data1_node *node_data;
254 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
257 node_data->u.data.what = DATA1I_text;
258 node_data->u.data.len = strlen (str);
259 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
263 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
264 const char *tag, const char *str,
267 data1_node *node = data1_search_tag (dh, at->child, tag);
269 return data1_add_tagdata_text (dh, at, tag, str, nmem);
272 data1_node *node_data = node->child;
273 node_data->u.data.what = DATA1I_text;
274 node_data->u.data.data = node_data->lbuf;
275 strcpy (node_data->u.data.data, str);
276 node_data->u.data.len = strlen (node_data->u.data.data);
281 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
282 struct zebDatabaseInfoB *zdi,
284 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
285 zebAttributeDetails zad,
286 const char *databaseName,
288 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
289 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
292 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
293 struct zebraCategoryListInfo *zcl,
297 static Record createRecord (Records records, int *sysno)
302 rec = rec_get (records, *sysno);
303 xfree (rec->info[recInfo_storeData]);
307 rec = rec_new (records);
310 rec->info[recInfo_fileType] =
311 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
312 rec->info[recInfo_databaseName] =
313 rec_strdup ("IR-Explain-1",
314 &rec->size[recInfo_databaseName]);
319 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag,
320 int (*updateH)(Record drec, data1_node *n))
322 struct zebDatabaseInfoB *zdi;
324 logf (LOG_DEBUG, "zebraExplain_close wr=%d", writeFlag);
328 /* write each database info record */
329 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
331 zebraExplain_writeDatabase (zei, zdi, 1);
332 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
333 zdi->databaseName, 1);
335 zebraExplain_writeTarget (zei, 1);
336 zebraExplain_writeCategoryList (zei,
339 assert (zei->accessInfo);
340 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
342 zebraExplain_writeAttributeSet (zei, o, 1);
343 for (o = zei->accessInfo->schemas; o; o = o->next)
346 /* zebraExplain_writeSchema (zei, o, 1); */
349 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
351 zebraExplain_writeDatabase (zei, zdi, 0);
352 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
353 zdi->databaseName, 0);
355 zebraExplain_writeTarget (zei, 0);
358 nmem_destroy (zei->nmem);
362 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
367 for (np = n->child; np; np = np->next)
374 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
376 len = np->child->u.data.len;
379 memcpy (str, np->child->u.data.data, len);
382 oid = odr_getoidbystr_nmem (zei->nmem, str);
384 for (ao = *op; ao; ao = ao->next)
385 if (!oid_oidcmp (oid, ao->oid))
392 ao = nmem_malloc (zei->nmem, sizeof(*ao));
402 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
403 zebAccessInfo *accessInfo)
409 *accessInfo = nmem_malloc (zei->nmem, sizeof(**accessInfo));
410 (*accessInfo)->attributeSetIds = NULL;
411 (*accessInfo)->schemas = NULL;
415 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
417 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
418 zebraExplain_mergeOids (zei, np,
419 &(*accessInfo)->attributeSetIds);
420 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
421 zebraExplain_mergeOids (zei, np,
422 &(*accessInfo)->schemas);
426 ZebraExplainInfo zebraExplain_open (
427 Records records, data1_handle dh,
431 int (*updateFunc)(void *handle, Record drec, data1_node *n))
434 ZebraExplainInfo zei;
435 struct zebDatabaseInfoB **zdip;
439 logf (LOG_DEBUG, "zebraExplain_open wr=%d", writeFlag);
440 zei = xmalloc (sizeof(*zei));
441 zei->updateHandle = updateHandle;
442 zei->updateFunc = updateFunc;
444 zei->curDatabaseInfo = NULL;
445 zei->records = records;
446 zei->nmem = nmem_create ();
450 zei->categoryList = nmem_malloc (zei->nmem,
451 sizeof(*zei->categoryList));
452 zei->categoryList->sysno = 0;
453 zei->categoryList->dirty = 0;
454 zei->categoryList->data1_categoryList = NULL;
457 tm = localtime (&our_time);
458 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
459 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
460 tm->tm_hour, tm->tm_min, tm->tm_sec);
462 zdip = &zei->databaseInfo;
463 trec = rec_get (records, 1); /* get "root" record */
465 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
466 if (trec) /* targetInfo already exists ... */
468 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
470 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
473 data1_pr_tree (zei->dh, zei->data1_target, stderr);
475 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
477 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
480 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
482 node_list = data1_search_tag (zei->dh, node_zebra->child,
484 for (np = node_list->child; np; np = np->next)
486 data1_node *node_name = NULL;
487 data1_node *node_id = NULL;
488 data1_node *node_aid = NULL;
490 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
492 for (np2 = np->child; np2; np2 = np2->next)
494 if (np2->which != DATA1N_tag)
496 if (!strcmp (np2->u.tag.tag, "name"))
497 node_name = np2->child;
498 else if (!strcmp (np2->u.tag.tag, "id"))
499 node_id = np2->child;
500 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
501 node_aid = np2->child;
503 assert (node_id && node_name && node_aid);
505 *zdip = nmem_malloc (zei->nmem, sizeof(**zdip));
507 (*zdip)->readFlag = 1;
509 (*zdip)->data1_database = NULL;
510 (*zdip)->recordCount = 0;
511 (*zdip)->recordBytes = 0;
512 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
514 (*zdip)->databaseName = nmem_malloc (zei->nmem,
515 1+node_name->u.data.len);
516 memcpy ((*zdip)->databaseName, node_name->u.data.data,
517 node_name->u.data.len);
518 (*zdip)->databaseName[node_name->u.data.len] = '\0';
519 (*zdip)->sysno = atoi_n (node_id->u.data.data,
520 node_id->u.data.len);
521 (*zdip)->attributeDetails =
522 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
523 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
524 node_aid->u.data.len);
525 (*zdip)->attributeDetails->readFlag = 1;
526 (*zdip)->attributeDetails->dirty = 0;
527 (*zdip)->attributeDetails->SUInfo = NULL;
529 zdip = &(*zdip)->next;
531 np = data1_search_tag (zei->dh, node_zebra->child,
534 assert (np && np->which == DATA1N_data);
535 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
537 np = data1_search_tag (zei->dh, node_zebra->child,
540 assert (np && np->which == DATA1N_data);
541 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
545 else /* create initial targetInfo */
547 data1_node *node_tgtinfo;
557 data1_read_sgml (zei->dh, zei->nmem,
558 "<explain><targetInfo>TargetInfo\n"
560 "<namedResultSets>1</>\n"
561 "<multipleDBSearch>1</>\n"
562 "<nicknames><name>Zebra</></>\n"
565 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
567 assert (node_tgtinfo);
569 zebraExplain_initCommonInfo (zei, node_tgtinfo);
570 zebraExplain_initAccessInfo (zei, node_tgtinfo);
572 /* write now because we want to be sure about the sysno */
573 trec = rec_new (records);
574 trec->info[recInfo_fileType] =
575 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
576 trec->info[recInfo_databaseName] =
577 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
579 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
580 trec->info[recInfo_storeData] = xmalloc (sgml_len);
581 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
582 trec->size[recInfo_storeData] = sgml_len;
584 rec_put (records, &trec);
588 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
590 if (!zei->categoryList->dirty)
592 struct zebraCategoryListInfo *zcl = zei->categoryList;
596 zcl->data1_categoryList =
597 data1_read_sgml (zei->dh, zei->nmem,
598 "<explain><categoryList>CategoryList\n"
600 node_cl = data1_search_tag (zei->dh,
601 zcl->data1_categoryList->child,
604 zebraExplain_initCommonInfo (zei, node_cl);
610 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
611 zebAttributeDetails zad)
614 struct zebSUInfoB **zsuip = &zad->SUInfo;
615 data1_node *node_adinfo, *node_zebra, *node_list, *np;
618 rec = rec_get (zei->records, zad->sysno);
620 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
622 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
624 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
626 node_list = data1_search_tag (zei->dh, node_zebra->child,
628 for (np = node_list->child; np; np = np->next)
630 data1_node *node_set = NULL;
631 data1_node *node_use = NULL;
632 data1_node *node_ordinal = NULL;
637 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
639 for (np2 = np->child; np2; np2 = np2->next)
641 if (np2->which != DATA1N_tag || !np2->child ||
642 np2->child->which != DATA1N_data)
644 if (!strcmp (np2->u.tag.tag, "set"))
645 node_set = np2->child;
646 else if (!strcmp (np2->u.tag.tag, "use"))
647 node_use = np2->child;
648 else if (!strcmp (np2->u.tag.tag, "ordinal"))
649 node_ordinal = np2->child;
651 assert (node_set && node_use && node_ordinal);
653 oid_str_len = node_set->u.data.len;
654 if (oid_str_len >= sizeof(oid_str))
655 oid_str_len = sizeof(oid_str)-1;
656 memcpy (oid_str, node_set->u.data.data, oid_str_len);
657 oid_str[oid_str_len] = '\0';
659 *zsuip = nmem_malloc (zei->nmem, sizeof(**zsuip));
660 (*zsuip)->info.set = oid_getvalbyname (oid_str);
662 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
663 node_use->u.data.len);
664 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
665 node_ordinal->u.data.len);
666 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
667 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
668 zsuip = &(*zsuip)->next;
675 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
676 struct zebDatabaseInfoB *zdi)
679 data1_node *node_dbinfo, *node_zebra, *np;
682 rec = rec_get (zei->records, zdi->sysno);
684 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
686 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
688 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
690 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
692 np = data1_search_tag (zei->dh, node_dbinfo->child,
694 if (np && np->child && np->child->which == DATA1N_data)
695 zdi->recordBytes = atoi_n (np->child->u.data.data,
696 np->child->u.data.len);
697 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
699 (np = data1_search_tag (zei->dh, np->child,
700 "recordCountActual")) &&
701 np->child->which == DATA1N_data)
703 zdi->recordCount = atoi_n (np->child->u.data.data,
704 np->child->u.data.len);
710 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
712 struct zebDatabaseInfoB *zdi;
715 if (zei->curDatabaseInfo &&
716 !strcmp (zei->curDatabaseInfo->databaseName, database))
718 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
720 if (!strcmp (zdi->databaseName, database))
726 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
731 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
733 zebraExplain_readDatabase (zei, zdi);
735 if (zdi->attributeDetails->readFlag)
738 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
740 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
742 zei->curDatabaseInfo = zdi;
746 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
748 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
750 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
751 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
752 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
755 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
757 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
759 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
762 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
764 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
765 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
766 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
769 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
770 zebAccessInfo accessInfo)
772 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
778 if ((p = accessInfo->attributeSetIds))
780 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
781 for (; p; p = p->next)
782 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
784 if ((p = accessInfo->schemas))
786 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
787 for (; p; p = p->next)
788 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
792 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
793 int explain_database)
795 struct zebDatabaseInfoB *zdi;
796 data1_node *node_dbinfo, *node_adinfo;
799 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
802 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
804 if (!strcmp (zdi->databaseName, database))
809 /* it's new really. make it */
810 zdi = nmem_malloc (zei->nmem, sizeof(*zdi));
811 zdi->next = zei->databaseInfo;
812 zei->databaseInfo = zdi;
814 zdi->recordCount = 0;
815 zdi->recordBytes = 0;
817 zdi->databaseName = nmem_strdup (zei->nmem, database);
819 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
824 zdi->data1_database =
825 data1_read_sgml (zei->dh, zei->nmem,
826 "<explain><databaseInfo>DatabaseInfo\n"
829 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
831 assert (node_dbinfo);
833 zebraExplain_initCommonInfo (zei, node_dbinfo);
834 zebraExplain_initAccessInfo (zei, node_dbinfo);
836 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
837 database, zei->nmem);
839 if (explain_database)
840 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
843 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
846 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
850 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
854 zei->curDatabaseInfo = zdi;
856 zdi->attributeDetails =
857 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
858 zdi->attributeDetails->readFlag = 0;
859 zdi->attributeDetails->sysno = 0;
860 zdi->attributeDetails->dirty = 1;
861 zdi->attributeDetails->SUInfo = NULL;
862 zdi->attributeDetails->data1_tree =
863 data1_read_sgml (zei->dh, zei->nmem,
864 "<explain><attributeDetails>AttributeDetails\n"
868 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
870 assert (node_adinfo);
872 zebraExplain_initCommonInfo (zei, node_adinfo);
877 static void writeAttributeValueDetails (ZebraExplainInfo zei,
878 zebAttributeDetails zad,
879 data1_node *node_atvs, data1_attset *attset)
882 struct zebSUInfoB *zsui;
883 int set_ordinal = attset->reference;
884 data1_attset_child *c;
886 for (c = attset->children; c; c = c->next)
887 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
888 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
890 data1_node *node_attvalue, *node_value;
891 if (set_ordinal != zsui->info.set)
893 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
895 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
897 data1_add_tagdata_int (zei->dh, node_value, "numeric",
898 zsui->info.use, zei->nmem);
902 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
903 struct zebraCategoryListInfo *zcl,
910 data1_node *node_ci, *node_categoryList;
912 static char *category[] = {
924 node_categoryList = zcl->data1_categoryList;
927 logf (LOG_LOG, "zebraExplain_writeCategoryList");
930 drec = createRecord (zei->records, &sysno);
932 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
935 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
938 for (i = 0; category[i]; i++)
940 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
941 "category", zei->nmem);
943 data1_add_tagdata_text (zei->dh, node_cat, "name",
944 category[i], zei->nmem);
946 /* extract *searchable* keys from it. We do this here, because
947 record count, etc. is affected */
949 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
951 /* convert to "SGML" and write it */
953 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
955 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList,
957 drec->info[recInfo_storeData] = xmalloc (sgml_len);
958 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
959 drec->size[recInfo_storeData] = sgml_len;
961 rec_put (zei->records, &drec);
964 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
965 zebAttributeDetails zad,
966 const char *databaseName,
972 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
973 struct zebSUInfoB *zsui;
981 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
984 drec = createRecord (zei->records, &zad->sysno);
985 assert (zad->data1_tree);
986 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
988 zebraExplain_updateCommonInfo (zei, node_adinfo);
990 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
991 databaseName, zei->nmem);
993 /* extract *searchable* keys from it. We do this here, because
994 record count, etc. is affected */
996 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
998 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
999 "attributesBySet", zei->nmem);
1003 data1_node *node_asd;
1004 data1_attset *attset;
1005 int set_ordinal = -1;
1006 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1008 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1009 && zsui->info.set > set_min)
1010 set_ordinal = zsui->info.set;
1012 if (set_ordinal < 0)
1014 set_min = set_ordinal;
1015 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1016 "attributeSetDetails", zei->nmem);
1018 attset = data1_attset_search_id (zei->dh, set_ordinal);
1021 zebraExplain_loadAttsets (zei->dh, zei->res);
1022 attset = data1_attset_search_id (zei->dh, set_ordinal);
1029 oe.proto = PROTO_Z3950;
1030 oe.oclass = CLASS_ATTSET;
1031 oe.value = set_ordinal;
1033 if (oid_ent_to_oid (&oe, oid))
1035 data1_node *node_abt, *node_atd, *node_atvs;
1036 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1039 node_abt = data1_add_tag (zei->dh, node_asd,
1040 "attributesByType", zei->nmem);
1041 node_atd = data1_add_tag (zei->dh, node_abt,
1042 "attributeTypeDetails", zei->nmem);
1043 data1_add_tagdata_int (zei->dh, node_atd,
1044 "type", 1, zei->nmem);
1045 node_atvs = data1_add_tag (zei->dh, node_atd,
1046 "attributeValues", zei->nmem);
1047 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1051 /* zebra info (private) */
1052 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1053 "zebraInfo", zei->nmem);
1054 node_list = data1_make_tag (zei->dh, node_zebra,
1055 "attrlist", zei->nmem);
1056 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1058 struct oident oident;
1060 data1_node *node_attr;
1062 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1064 oident.proto = PROTO_Z3950;
1065 oident.oclass = CLASS_ATTSET;
1066 oident.value = zsui->info.set;
1067 oid_ent_to_oid (&oident, oid);
1069 data1_add_tagdata_text (zei->dh, node_attr, "set",
1070 oident.desc, zei->nmem);
1071 data1_add_tagdata_int (zei->dh, node_attr, "use",
1072 zsui->info.use, zei->nmem);
1073 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1074 zsui->info.ordinal, zei->nmem);
1076 /* convert to "SGML" and write it */
1078 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1080 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1082 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1083 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1084 drec->size[recInfo_storeData] = sgml_len;
1086 rec_put (zei->records, &drec);
1089 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1090 struct zebDatabaseInfoB *zdi,
1096 data1_node *node_dbinfo, *node_count, *node_zebra;
1103 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1105 drec = createRecord (zei->records, &zdi->sysno);
1106 assert (zdi->data1_database);
1107 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1110 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1111 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1113 /* extract *searchable* keys from it. We do this here, because
1114 record count, etc. is affected */
1116 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1118 node_count = data1_make_tag (zei->dh, node_dbinfo,
1119 "recordCount", zei->nmem);
1120 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1121 zdi->recordCount, zei->nmem);
1123 /* zebra info (private) */
1124 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1125 "zebraInfo", zei->nmem);
1126 data1_add_tagdata_int (zei->dh, node_zebra,
1127 "recordBytes", zdi->recordBytes, zei->nmem);
1128 /* convert to "SGML" and write it */
1130 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1132 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1134 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1135 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1136 drec->size[recInfo_storeData] = sgml_len;
1138 rec_put (zei->records, &drec);
1141 static void writeAttributeValues (ZebraExplainInfo zei,
1142 data1_node *node_values,
1143 data1_attset *attset)
1146 data1_attset_child *c;
1151 for (c = attset->children; c; c = c->next)
1152 writeAttributeValues (zei, node_values, c->child);
1153 for (atts = attset->atts; atts; atts = atts->next)
1155 data1_node *node_value;
1157 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1159 data1_add_tagdata_text (zei->dh, node_value, "name",
1160 atts->name, zei->nmem);
1161 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1162 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1163 atts->value, zei->nmem);
1168 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1175 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1176 data1_node *node_values;
1177 struct oident *entp;
1178 struct data1_attset *attset = NULL;
1180 if ((entp = oid_getentbyoid (o->oid)))
1181 attset = data1_attset_search_id (zei->dh, entp->value);
1184 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1185 attset ? attset->name : "<unknown>");
1188 drec = createRecord (zei->records, &o->sysno);
1190 data1_read_sgml (zei->dh, zei->nmem,
1191 "<explain><attributeSetInfo>AttributeSetInfo\n"
1194 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1195 "attributeSetInfo");
1197 zebraExplain_initCommonInfo (zei, node_attinfo);
1198 zebraExplain_updateCommonInfo (zei, node_attinfo);
1200 data1_add_tagdata_oid (zei->dh, node_attinfo,
1201 "oid", o->oid, zei->nmem);
1202 if (attset && attset->name)
1203 data1_add_tagdata_text (zei->dh, node_attinfo,
1204 "name", attset->name, zei->nmem);
1206 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1207 "attributes", zei->nmem);
1208 node_atttype = data1_make_tag (zei->dh, node_attributes,
1209 "attributeType", zei->nmem);
1210 data1_add_tagdata_text (zei->dh, node_atttype,
1211 "name", "Use", zei->nmem);
1212 data1_add_tagdata_text (zei->dh, node_atttype,
1213 "description", "Use Attribute", zei->nmem);
1214 data1_add_tagdata_int (zei->dh, node_atttype,
1215 "type", 1, zei->nmem);
1216 node_values = data1_add_tag (zei->dh, node_atttype,
1217 "attributeValues", zei->nmem);
1219 writeAttributeValues (zei, node_values, attset);
1221 /* extract *searchable* keys from it. We do this here, because
1222 record count, etc. is affected */
1224 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1225 /* convert to "SGML" and write it */
1227 data1_pr_tree (zei->dh, node_root, stderr);
1229 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1230 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1231 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1232 drec->size[recInfo_storeData] = sgml_len;
1234 rec_put (zei->records, &drec);
1237 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1239 struct zebDatabaseInfoB *zdi;
1240 data1_node *node_tgtinfo, *node_list, *node_zebra;
1249 trec = rec_get (zei->records, 1);
1250 xfree (trec->info[recInfo_storeData]);
1252 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1254 assert (node_tgtinfo);
1256 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1257 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1259 /* convert to "SGML" and write it */
1261 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1263 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1264 "zebraInfo", zei->nmem);
1265 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1266 ZEBRAVER, zei->nmem);
1267 node_list = data1_add_tag (zei->dh, node_zebra,
1268 "databaseList", zei->nmem);
1269 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1271 data1_node *node_db;
1272 node_db = data1_add_tag (zei->dh, node_list,
1273 "database", zei->nmem);
1274 data1_add_tagdata_text (zei->dh, node_db, "name",
1275 zdi->databaseName, zei->nmem);
1276 data1_add_tagdata_int (zei->dh, node_db, "id",
1277 zdi->sysno, zei->nmem);
1278 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1279 zdi->attributeDetails->sysno, zei->nmem);
1281 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1282 zei->ordinalSU, zei->nmem);
1284 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1285 zei->runNumber, zei->nmem);
1288 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1290 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1292 trec->info[recInfo_storeData] = xmalloc (sgml_len);
1293 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1294 trec->size[recInfo_storeData] = sgml_len;
1296 rec_put (zei->records, &trec);
1299 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1301 struct zebSUInfoB *zsui;
1303 assert (zei->curDatabaseInfo);
1304 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1305 zsui; zsui=zsui->next)
1306 if (zsui->info.use == use && zsui->info.set == set)
1307 return zsui->info.ordinal;
1311 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1312 zebAccessObject *op,
1317 for (ao = *op; ao; ao = ao->next)
1318 if (!oid_oidcmp (oid, ao->oid))
1322 ao = nmem_malloc (zei->nmem, sizeof(*ao));
1325 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1332 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1337 oe.proto = PROTO_Z3950;
1338 oe.oclass = CLASS_ATTSET;
1341 if (oid_ent_to_oid (&oe, oid))
1343 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1344 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1345 accessInfo->attributeSetIds, oid);
1349 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1351 struct zebSUInfoB *zsui;
1353 assert (zei->curDatabaseInfo);
1354 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1355 zsui; zsui=zsui->next)
1356 if (zsui->info.use == use && zsui->info.set == set)
1358 zebraExplain_addAttributeSet (zei, set);
1359 zsui = nmem_malloc (zei->nmem, sizeof(*zsui));
1360 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1361 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1362 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1364 zsui->info.set = set;
1365 zsui->info.use = use;
1366 zsui->info.ordinal = (zei->ordinalSU)++;
1367 return zsui->info.ordinal;
1370 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1372 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1373 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1374 accessInfo->schemas, oid);
1377 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1379 assert (zei->curDatabaseInfo);
1383 zei->curDatabaseInfo->recordBytes += adjust_num;
1384 zei->curDatabaseInfo->dirty = 1;
1388 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1390 assert (zei->curDatabaseInfo);
1394 zei->curDatabaseInfo->recordCount += adjust_num;
1395 zei->curDatabaseInfo->dirty = 1;
1399 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1403 return zei->runNumber += adjust_num;
1406 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1408 RecordAttr *recordAttr;
1410 if (rec->info[recInfo_attr])
1411 return (RecordAttr *) rec->info[recInfo_attr];
1412 recordAttr = xmalloc (sizeof(*recordAttr));
1413 rec->info[recInfo_attr] = (char *) recordAttr;
1414 rec->size[recInfo_attr] = sizeof(*recordAttr);
1416 recordAttr->recordSize = 0;
1417 recordAttr->recordOffset = 0;
1418 recordAttr->runNumber = zei->runNumber;
1422 static void att_loadset(void *p, const char *n, const char *name)
1424 data1_handle dh = p;
1425 if (!data1_get_attset (dh, name))
1426 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1429 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1431 res_trav(res, "attset", dh, att_loadset);
1435 zebraExplain_addSU adds to AttributeDetails for a database and
1436 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1437 exist for the database.
1439 If the database doesn't exist globally (in TargetInfo) an
1440 AttributeSetInfo must be added (globally).