2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.24 2002-02-20 23:07:54 adam Exp $
26 struct zebSUInfo info;
27 struct zebSUInfoB *next;
30 typedef struct zebAccessObjectB *zebAccessObject;
31 struct zebAccessObjectB {
38 typedef struct zebAccessInfoB *zebAccessInfo;
39 struct zebAccessInfoB {
40 zebAccessObject attributeSetIds;
41 zebAccessObject schemas;
45 struct zebSUInfoB *SUInfo;
49 data1_node *data1_tree;
50 } *zebAttributeDetails;
52 struct zebDatabaseInfoB {
53 zebAttributeDetails attributeDetails;
55 data1_node *data1_database;
56 int recordCount; /* records in db */
57 int recordBytes; /* size of records */
58 int sysno; /* sysno of database info */
59 int readFlag; /* 1: read is needed when referenced; 0 if not */
60 int dirty; /* 1: database is dirty: write is needed */
61 struct zebDatabaseInfoB *next;
62 zebAccessInfo accessInfo;
65 struct zebraExplainAttset {
68 struct zebraExplainAttset *next;
71 struct zebraCategoryListInfo {
74 data1_node *data1_categoryList;
77 struct zebraExplainInfo {
84 struct zebraExplainAttset *attsets;
86 data1_node *data1_target;
87 struct zebraCategoryListInfo *categoryList;
88 struct zebDatabaseInfoB *databaseInfo;
89 struct zebDatabaseInfoB *curDatabaseInfo;
90 zebAccessInfo accessInfo;
91 char date[15]; /* YYYY MMDD HH MM SS */
92 int (*updateFunc)(void *handle, Record drec, data1_node *n);
96 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
97 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
99 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
101 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
104 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
107 logf (LOG_DEBUG, "data1_search_tag %s", tag);
108 for (; n; n = n->next)
109 if (n->which == DATA1N_tag && n->u.tag.tag &&
110 !yaz_matchstr (tag, n->u.tag.tag))
112 logf (LOG_DEBUG, " found");
115 logf (LOG_DEBUG, " not found");
119 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
120 const char *tag, NMEM nmem)
122 data1_node *partag = get_parent_tag(dh, at);
123 data1_node *res = data1_mk_node_type (dh, nmem, DATA1N_tag);
124 data1_element *e = NULL;
127 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
130 e = partag->u.tag.element;
132 data1_getelementbytagname (dh, at->root->u.root.absyn,
134 res->root = at->root;
139 assert (at->last_child);
140 at->last_child->next = res;
142 at->last_child = res;
146 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
147 const char *tag, NMEM nmem)
149 data1_node *node = data1_search_tag (dh, at->child, tag);
151 node = data1_add_tag (dh, at, tag, nmem);
153 node->child = node->last_child = NULL;
157 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
158 const char *tag, int num,
161 data1_node *node_data;
163 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
166 node_data->u.data.what = DATA1I_num;
167 node_data->u.data.data = node_data->lbuf;
168 sprintf (node_data->u.data.data, "%d", num);
169 node_data->u.data.len = strlen (node_data->u.data.data);
173 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
174 const char *tag, Odr_oid *oid,
177 data1_node *node_data;
178 char str[128], *p = str;
181 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
185 for (ii = oid; *ii >= 0; ii++)
189 sprintf (p, "%d", *ii);
192 node_data->u.data.what = DATA1I_oid;
193 node_data->u.data.len = strlen (str);
194 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
199 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
200 const char *tag, const char *str,
203 data1_node *node_data;
205 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
208 node_data->u.data.what = DATA1I_text;
209 node_data->u.data.len = strlen (str);
210 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
214 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
215 const char *tag, const char *str,
218 data1_node *node = data1_search_tag (dh, at->child, tag);
220 return data1_add_tagdata_text (dh, at, tag, str, nmem);
223 data1_node *node_data = node->child;
224 node_data->u.data.what = DATA1I_text;
225 node_data->u.data.len = strlen (str);
226 node_data->u.data.data = data1_insert_string (dh, node_data,
232 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
233 struct zebDatabaseInfoB *zdi,
235 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
236 zebAttributeDetails zad,
237 const char *databaseName,
239 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
240 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
243 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
244 struct zebraCategoryListInfo *zcl,
248 static Record createRecord (Records records, int *sysno)
253 rec = rec_get (records, *sysno);
254 xfree (rec->info[recInfo_storeData]);
258 rec = rec_new (records);
261 rec->info[recInfo_fileType] =
262 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
263 rec->info[recInfo_databaseName] =
264 rec_strdup ("IR-Explain-1",
265 &rec->size[recInfo_databaseName]);
270 void zebraExplain_flush (ZebraExplainInfo zei, int writeFlag, void *handle)
274 zei->updateHandle = handle;
277 struct zebDatabaseInfoB *zdi;
280 /* write each database info record */
281 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
283 zebraExplain_writeDatabase (zei, zdi, 1);
284 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
285 zdi->databaseName, 1);
287 zebraExplain_writeTarget (zei, 1);
288 zebraExplain_writeCategoryList (zei,
291 assert (zei->accessInfo);
292 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
294 zebraExplain_writeAttributeSet (zei, o, 1);
295 for (o = zei->accessInfo->schemas; o; o = o->next)
298 /* zebraExplain_writeSchema (zei, o, 1); */
301 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
303 zebraExplain_writeDatabase (zei, zdi, 0);
304 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
305 zdi->databaseName, 0);
307 zebraExplain_writeTarget (zei, 0);
311 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag)
314 logf (LOG_LOG, "zebraExplain_close wr=%d", writeFlag);
318 zebraExplain_flush (zei, writeFlag, zei->updateHandle);
319 nmem_destroy (zei->nmem);
322 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
327 for (np = n->child; np; np = np->next)
334 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
336 len = np->child->u.data.len;
339 memcpy (str, np->child->u.data.data, len);
342 oid = odr_getoidbystr_nmem (zei->nmem, str);
344 for (ao = *op; ao; ao = ao->next)
345 if (!oid_oidcmp (oid, ao->oid))
352 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
362 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
363 zebAccessInfo *accessInfo)
369 *accessInfo = (zebAccessInfo)
370 nmem_malloc (zei->nmem, sizeof(**accessInfo));
371 (*accessInfo)->attributeSetIds = NULL;
372 (*accessInfo)->schemas = NULL;
376 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
378 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
379 zebraExplain_mergeOids (zei, np,
380 &(*accessInfo)->attributeSetIds);
381 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
382 zebraExplain_mergeOids (zei, np,
383 &(*accessInfo)->schemas);
387 ZebraExplainInfo zebraExplain_open (
388 Records records, data1_handle dh,
392 int (*updateFunc)(void *handle, Record drec, data1_node *n))
395 ZebraExplainInfo zei;
396 struct zebDatabaseInfoB **zdip;
399 NMEM nmem = nmem_create ();
402 logf (LOG_LOG, "zebraExplain_open wr=%d", writeFlag);
404 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
405 zei->updateHandle = updateHandle;
406 zei->updateFunc = updateFunc;
408 zei->curDatabaseInfo = NULL;
409 zei->records = records;
414 zei->categoryList = (struct zebraCategoryListInfo *)
415 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
416 zei->categoryList->sysno = 0;
417 zei->categoryList->dirty = 0;
418 zei->categoryList->data1_categoryList = NULL;
421 tm = localtime (&our_time);
422 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
423 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
424 tm->tm_hour, tm->tm_min, tm->tm_sec);
426 zdip = &zei->databaseInfo;
427 trec = rec_get (records, 1); /* get "root" record */
432 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
433 if (trec) /* targetInfo already exists ... */
435 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
437 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
438 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
440 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
441 nmem_destroy (zei->nmem);
445 data1_pr_tree (zei->dh, zei->data1_target, stderr);
447 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
449 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
452 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
457 node_list = data1_search_tag (zei->dh, node_zebra->child,
460 np = node_list->child;
462 for (; np; np = np->next)
464 data1_node *node_name = NULL;
465 data1_node *node_id = NULL;
466 data1_node *node_aid = NULL;
468 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
470 for (np2 = np->child; np2; np2 = np2->next)
472 if (np2->which != DATA1N_tag)
474 if (!strcmp (np2->u.tag.tag, "name"))
475 node_name = np2->child;
476 else if (!strcmp (np2->u.tag.tag, "id"))
477 node_id = np2->child;
478 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
479 node_aid = np2->child;
481 assert (node_id && node_name && node_aid);
483 *zdip = (struct zebDatabaseInfoB *)
484 nmem_malloc (zei->nmem, sizeof(**zdip));
485 (*zdip)->readFlag = 1;
487 (*zdip)->data1_database = NULL;
488 (*zdip)->recordCount = 0;
489 (*zdip)->recordBytes = 0;
490 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
492 (*zdip)->databaseName = (char *)
493 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
494 memcpy ((*zdip)->databaseName, node_name->u.data.data,
495 node_name->u.data.len);
496 (*zdip)->databaseName[node_name->u.data.len] = '\0';
497 (*zdip)->sysno = atoi_n (node_id->u.data.data,
498 node_id->u.data.len);
499 (*zdip)->attributeDetails = (zebAttributeDetails)
500 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
501 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
502 node_aid->u.data.len);
503 (*zdip)->attributeDetails->readFlag = 1;
504 (*zdip)->attributeDetails->dirty = 0;
505 (*zdip)->attributeDetails->SUInfo = NULL;
507 zdip = &(*zdip)->next;
511 np = data1_search_tag (zei->dh, node_zebra->child,
514 assert (np && np->which == DATA1N_data);
515 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
517 np = data1_search_tag (zei->dh, node_zebra->child,
520 assert (np && np->which == DATA1N_data);
521 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
526 else /* create initial targetInfo */
528 data1_node *node_tgtinfo;
537 data1_read_sgml (zei->dh, zei->nmem,
538 "<explain><targetInfo>TargetInfo\n"
540 "<namedResultSets>1</>\n"
541 "<multipleDBSearch>1</>\n"
542 "<nicknames><name>Zebra</></>\n"
544 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
546 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
547 nmem_destroy (zei->nmem);
550 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
552 assert (node_tgtinfo);
554 zebraExplain_initCommonInfo (zei, node_tgtinfo);
555 zebraExplain_initAccessInfo (zei, node_tgtinfo);
557 /* write now because we want to be sure about the sysno */
558 trec = rec_new (records);
559 trec->info[recInfo_fileType] =
560 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
561 trec->info[recInfo_databaseName] =
562 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
564 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
565 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
566 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
567 trec->size[recInfo_storeData] = sgml_len;
569 rec_put (records, &trec);
573 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
575 if (!zei->categoryList->dirty)
577 struct zebraCategoryListInfo *zcl = zei->categoryList;
581 zcl->data1_categoryList =
582 data1_read_sgml (zei->dh, zei->nmem,
583 "<explain><categoryList>CategoryList\n"
586 if (zcl->data1_categoryList)
588 assert (zcl->data1_categoryList->child);
589 node_cl = data1_search_tag (zei->dh,
590 zcl->data1_categoryList->child,
593 zebraExplain_initCommonInfo (zei, node_cl);
600 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
601 zebAttributeDetails zad)
604 struct zebSUInfoB **zsuip = &zad->SUInfo;
605 data1_node *node_adinfo, *node_zebra, *node_list, *np;
608 rec = rec_get (zei->records, zad->sysno);
610 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
612 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
614 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
616 node_list = data1_search_tag (zei->dh, node_zebra->child,
618 for (np = node_list->child; np; np = np->next)
620 data1_node *node_set = NULL;
621 data1_node *node_use = NULL;
622 data1_node *node_ordinal = NULL;
627 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
629 for (np2 = np->child; np2; np2 = np2->next)
631 if (np2->which != DATA1N_tag || !np2->child ||
632 np2->child->which != DATA1N_data)
634 if (!strcmp (np2->u.tag.tag, "set"))
635 node_set = np2->child;
636 else if (!strcmp (np2->u.tag.tag, "use"))
637 node_use = np2->child;
638 else if (!strcmp (np2->u.tag.tag, "ordinal"))
639 node_ordinal = np2->child;
641 assert (node_set && node_use && node_ordinal);
643 oid_str_len = node_set->u.data.len;
644 if (oid_str_len >= (int) sizeof(oid_str))
645 oid_str_len = sizeof(oid_str)-1;
646 memcpy (oid_str, node_set->u.data.data, oid_str_len);
647 oid_str[oid_str_len] = '\0';
649 *zsuip = (struct zebSUInfoB *)
650 nmem_malloc (zei->nmem, sizeof(**zsuip));
651 (*zsuip)->info.set = oid_getvalbyname (oid_str);
653 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
654 node_use->u.data.len);
655 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
656 node_ordinal->u.data.len);
657 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
658 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
659 zsuip = &(*zsuip)->next;
666 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
667 struct zebDatabaseInfoB *zdi)
670 data1_node *node_dbinfo, *node_zebra, *np;
673 rec = rec_get (zei->records, zdi->sysno);
675 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
677 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
679 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
681 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
684 && (np = data1_search_tag (zei->dh, node_zebra->child,
686 && np->child && np->child->which == DATA1N_data)
687 zdi->recordBytes = atoi_n (np->child->u.data.data,
688 np->child->u.data.len);
689 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
691 (np = data1_search_tag (zei->dh, np->child,
692 "recordCountActual")) &&
693 np->child->which == DATA1N_data)
695 zdi->recordCount = atoi_n (np->child->u.data.data,
696 np->child->u.data.len);
702 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
704 struct zebDatabaseInfoB *zdi;
707 if (zei->curDatabaseInfo &&
708 !strcmp (zei->curDatabaseInfo->databaseName, database))
710 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
712 if (!strcmp (zdi->databaseName, database))
718 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
723 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
725 zebraExplain_readDatabase (zei, zdi);
727 if (zdi->attributeDetails->readFlag)
730 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
732 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
734 zei->curDatabaseInfo = zdi;
738 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
740 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
742 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
743 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
744 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
747 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
749 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
751 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
754 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
756 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
757 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
758 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
761 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
762 zebAccessInfo accessInfo)
764 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
770 if ((p = accessInfo->attributeSetIds))
772 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
773 for (; p; p = p->next)
774 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
776 if ((p = accessInfo->schemas))
778 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
779 for (; p; p = p->next)
780 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
784 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
785 int explain_database)
787 struct zebDatabaseInfoB *zdi;
788 data1_node *node_dbinfo, *node_adinfo;
791 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
794 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
796 if (!strcmp (zdi->databaseName, database))
801 /* it's new really. make it */
802 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
803 zdi->next = zei->databaseInfo;
804 zei->databaseInfo = zdi;
806 zdi->recordCount = 0;
807 zdi->recordBytes = 0;
809 zdi->databaseName = nmem_strdup (zei->nmem, database);
811 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
816 zdi->data1_database =
817 data1_read_sgml (zei->dh, zei->nmem,
818 "<explain><databaseInfo>DatabaseInfo\n"
820 if (!zdi->data1_database)
823 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
825 assert (node_dbinfo);
827 zebraExplain_initCommonInfo (zei, node_dbinfo);
828 zebraExplain_initAccessInfo (zei, node_dbinfo);
830 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
831 database, zei->nmem);
833 if (explain_database)
834 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
837 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
840 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
844 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
848 zei->curDatabaseInfo = zdi;
850 zdi->attributeDetails = (zebAttributeDetails)
851 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
852 zdi->attributeDetails->readFlag = 0;
853 zdi->attributeDetails->sysno = 0;
854 zdi->attributeDetails->dirty = 1;
855 zdi->attributeDetails->SUInfo = NULL;
856 zdi->attributeDetails->data1_tree =
857 data1_read_sgml (zei->dh, zei->nmem,
858 "<explain><attributeDetails>AttributeDetails\n"
862 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
864 assert (node_adinfo);
866 zebraExplain_initCommonInfo (zei, node_adinfo);
871 static void writeAttributeValueDetails (ZebraExplainInfo zei,
872 zebAttributeDetails zad,
873 data1_node *node_atvs, data1_attset *attset)
876 struct zebSUInfoB *zsui;
877 int set_ordinal = attset->reference;
878 data1_attset_child *c;
880 for (c = attset->children; c; c = c->next)
881 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
882 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
884 data1_node *node_attvalue, *node_value;
885 if (set_ordinal != zsui->info.set)
887 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
889 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
891 data1_add_tagdata_int (zei->dh, node_value, "numeric",
892 zsui->info.use, zei->nmem);
896 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
897 struct zebraCategoryListInfo *zcl,
904 data1_node *node_ci, *node_categoryList;
906 static char *category[] = {
918 node_categoryList = zcl->data1_categoryList;
921 logf (LOG_LOG, "zebraExplain_writeCategoryList");
924 drec = createRecord (zei->records, &sysno);
926 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
929 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
932 for (i = 0; category[i]; i++)
934 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
935 "category", zei->nmem);
937 data1_add_tagdata_text (zei->dh, node_cat, "name",
938 category[i], zei->nmem);
940 /* extract *searchable* keys from it. We do this here, because
941 record count, etc. is affected */
943 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
945 /* convert to "SGML" and write it */
947 data1_pr_tree (zei->dh, node_categoryList, stderr);
949 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
950 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
951 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
952 drec->size[recInfo_storeData] = sgml_len;
954 rec_put (zei->records, &drec);
957 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
958 zebAttributeDetails zad,
959 const char *databaseName,
965 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
966 struct zebSUInfoB *zsui;
974 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
977 drec = createRecord (zei->records, &zad->sysno);
978 assert (zad->data1_tree);
979 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
981 zebraExplain_updateCommonInfo (zei, node_adinfo);
983 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
984 databaseName, zei->nmem);
986 /* extract *searchable* keys from it. We do this here, because
987 record count, etc. is affected */
989 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
991 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
992 "attributesBySet", zei->nmem);
996 data1_node *node_asd;
997 data1_attset *attset;
998 int set_ordinal = -1;
999 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1001 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1002 && zsui->info.set > set_min)
1003 set_ordinal = zsui->info.set;
1005 if (set_ordinal < 0)
1007 set_min = set_ordinal;
1008 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1009 "attributeSetDetails", zei->nmem);
1011 attset = data1_attset_search_id (zei->dh, set_ordinal);
1014 zebraExplain_loadAttsets (zei->dh, zei->res);
1015 attset = data1_attset_search_id (zei->dh, set_ordinal);
1022 oe.proto = PROTO_Z3950;
1023 oe.oclass = CLASS_ATTSET;
1024 oe.value = (enum oid_value) set_ordinal;
1026 if (oid_ent_to_oid (&oe, oid))
1028 data1_node *node_abt, *node_atd, *node_atvs;
1029 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1032 node_abt = data1_add_tag (zei->dh, node_asd,
1033 "attributesByType", zei->nmem);
1034 node_atd = data1_add_tag (zei->dh, node_abt,
1035 "attributeTypeDetails", zei->nmem);
1036 data1_add_tagdata_int (zei->dh, node_atd,
1037 "type", 1, zei->nmem);
1038 node_atvs = data1_add_tag (zei->dh, node_atd,
1039 "attributeValues", zei->nmem);
1040 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1044 /* zebra info (private) */
1045 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1046 "zebraInfo", zei->nmem);
1047 node_list = data1_make_tag (zei->dh, node_zebra,
1048 "attrlist", zei->nmem);
1049 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1051 struct oident oident;
1053 data1_node *node_attr;
1055 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1057 oident.proto = PROTO_Z3950;
1058 oident.oclass = CLASS_ATTSET;
1059 oident.value = (enum oid_value) zsui->info.set;
1060 oid_ent_to_oid (&oident, oid);
1062 data1_add_tagdata_text (zei->dh, node_attr, "set",
1063 oident.desc, zei->nmem);
1064 data1_add_tagdata_int (zei->dh, node_attr, "use",
1065 zsui->info.use, zei->nmem);
1066 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1067 zsui->info.ordinal, zei->nmem);
1069 /* convert to "SGML" and write it */
1071 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1073 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1075 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1076 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1077 drec->size[recInfo_storeData] = sgml_len;
1079 rec_put (zei->records, &drec);
1082 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1083 struct zebDatabaseInfoB *zdi,
1089 data1_node *node_dbinfo, *node_count, *node_zebra;
1096 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1098 drec = createRecord (zei->records, &zdi->sysno);
1099 assert (zdi->data1_database);
1100 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1103 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1104 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1106 /* extract *searchable* keys from it. We do this here, because
1107 record count, etc. is affected */
1109 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1111 node_count = data1_make_tag (zei->dh, node_dbinfo,
1112 "recordCount", zei->nmem);
1113 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1114 zdi->recordCount, zei->nmem);
1116 /* zebra info (private) */
1117 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1118 "zebraInfo", zei->nmem);
1119 data1_add_tagdata_int (zei->dh, node_zebra,
1120 "recordBytes", zdi->recordBytes, zei->nmem);
1121 /* convert to "SGML" and write it */
1123 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1125 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1127 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1128 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1129 drec->size[recInfo_storeData] = sgml_len;
1131 rec_put (zei->records, &drec);
1134 static void writeAttributeValues (ZebraExplainInfo zei,
1135 data1_node *node_values,
1136 data1_attset *attset)
1139 data1_attset_child *c;
1144 for (c = attset->children; c; c = c->next)
1145 writeAttributeValues (zei, node_values, c->child);
1146 for (atts = attset->atts; atts; atts = atts->next)
1148 data1_node *node_value;
1150 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1152 data1_add_tagdata_text (zei->dh, node_value, "name",
1153 atts->name, zei->nmem);
1154 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1155 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1156 atts->value, zei->nmem);
1161 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1168 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1169 data1_node *node_values;
1170 struct oident *entp;
1171 struct data1_attset *attset = NULL;
1173 if ((entp = oid_getentbyoid (o->oid)))
1174 attset = data1_attset_search_id (zei->dh, entp->value);
1177 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1178 attset ? attset->name : "<unknown>");
1181 drec = createRecord (zei->records, &o->sysno);
1183 data1_read_sgml (zei->dh, zei->nmem,
1184 "<explain><attributeSetInfo>AttributeSetInfo\n"
1187 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1188 "attributeSetInfo");
1190 zebraExplain_initCommonInfo (zei, node_attinfo);
1191 zebraExplain_updateCommonInfo (zei, node_attinfo);
1193 data1_add_tagdata_oid (zei->dh, node_attinfo,
1194 "oid", o->oid, zei->nmem);
1195 if (attset && attset->name)
1196 data1_add_tagdata_text (zei->dh, node_attinfo,
1197 "name", attset->name, zei->nmem);
1199 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1200 "attributes", zei->nmem);
1201 node_atttype = data1_make_tag (zei->dh, node_attributes,
1202 "attributeType", zei->nmem);
1203 data1_add_tagdata_text (zei->dh, node_atttype,
1204 "name", "Use", zei->nmem);
1205 data1_add_tagdata_text (zei->dh, node_atttype,
1206 "description", "Use Attribute", zei->nmem);
1207 data1_add_tagdata_int (zei->dh, node_atttype,
1208 "type", 1, zei->nmem);
1209 node_values = data1_add_tag (zei->dh, node_atttype,
1210 "attributeValues", zei->nmem);
1212 writeAttributeValues (zei, node_values, attset);
1214 /* extract *searchable* keys from it. We do this here, because
1215 record count, etc. is affected */
1217 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1218 /* convert to "SGML" and write it */
1220 data1_pr_tree (zei->dh, node_root, stderr);
1222 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1223 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1224 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1225 drec->size[recInfo_storeData] = sgml_len;
1227 rec_put (zei->records, &drec);
1230 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1232 struct zebDatabaseInfoB *zdi;
1233 data1_node *node_tgtinfo, *node_list, *node_zebra;
1242 trec = rec_get (zei->records, 1);
1243 xfree (trec->info[recInfo_storeData]);
1245 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1247 assert (node_tgtinfo);
1249 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1250 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1252 /* convert to "SGML" and write it */
1254 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1256 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1257 "zebraInfo", zei->nmem);
1258 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1259 ZEBRAVER, zei->nmem);
1260 node_list = data1_add_tag (zei->dh, node_zebra,
1261 "databaseList", zei->nmem);
1262 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1264 data1_node *node_db;
1265 node_db = data1_add_tag (zei->dh, node_list,
1266 "database", zei->nmem);
1267 data1_add_tagdata_text (zei->dh, node_db, "name",
1268 zdi->databaseName, zei->nmem);
1269 data1_add_tagdata_int (zei->dh, node_db, "id",
1270 zdi->sysno, zei->nmem);
1271 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1272 zdi->attributeDetails->sysno, zei->nmem);
1274 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1275 zei->ordinalSU, zei->nmem);
1277 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1278 zei->runNumber, zei->nmem);
1281 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1283 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1285 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1286 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1287 trec->size[recInfo_storeData] = sgml_len;
1289 rec_put (zei->records, &trec);
1292 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1294 struct zebSUInfoB *zsui;
1296 assert (zei->curDatabaseInfo);
1297 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1298 zsui; zsui=zsui->next)
1299 if (zsui->info.use == use && zsui->info.set == set)
1300 return zsui->info.ordinal;
1304 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1305 const char **db, int *set, int *use)
1307 struct zebDatabaseInfoB *zdb;
1308 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1310 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1311 for ( ;zsui; zsui = zsui->next)
1312 if (zsui->info.ordinal == ord)
1314 *db = zdb->databaseName;
1315 *set = zsui->info.set;
1316 *use = zsui->info.use;
1323 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1324 zebAccessObject *op,
1329 for (ao = *op; ao; ao = ao->next)
1330 if (!oid_oidcmp (oid, ao->oid))
1334 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1337 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1344 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1349 oe.proto = PROTO_Z3950;
1350 oe.oclass = CLASS_ATTSET;
1351 oe.value = (enum oid_value) set;
1353 if (oid_ent_to_oid (&oe, oid))
1355 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1356 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1357 accessInfo->attributeSetIds, oid);
1361 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1363 struct zebSUInfoB *zsui;
1365 assert (zei->curDatabaseInfo);
1366 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1367 zsui; zsui=zsui->next)
1368 if (zsui->info.use == use && zsui->info.set == set)
1370 zebraExplain_addAttributeSet (zei, set);
1371 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1372 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1373 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1374 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1376 zsui->info.set = set;
1377 zsui->info.use = use;
1378 zsui->info.ordinal = (zei->ordinalSU)++;
1379 return zsui->info.ordinal;
1382 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1384 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1385 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1386 accessInfo->schemas, oid);
1389 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1391 assert (zei->curDatabaseInfo);
1395 zei->curDatabaseInfo->recordBytes += adjust_num;
1396 zei->curDatabaseInfo->dirty = 1;
1400 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1402 assert (zei->curDatabaseInfo);
1406 zei->curDatabaseInfo->recordCount += adjust_num;
1407 zei->curDatabaseInfo->dirty = 1;
1411 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1415 return zei->runNumber += adjust_num;
1418 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1420 RecordAttr *recordAttr;
1422 if (rec->info[recInfo_attr])
1423 return (RecordAttr *) rec->info[recInfo_attr];
1424 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1425 rec->info[recInfo_attr] = (char *) recordAttr;
1426 rec->size[recInfo_attr] = sizeof(*recordAttr);
1428 recordAttr->recordSize = 0;
1429 recordAttr->recordOffset = 0;
1430 recordAttr->runNumber = zei->runNumber;
1434 static void att_loadset(void *p, const char *n, const char *name)
1436 data1_handle dh = (data1_handle) p;
1437 if (!data1_get_attset (dh, name))
1438 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1441 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1443 res_trav(res, "attset", dh, att_loadset);
1447 zebraExplain_addSU adds to AttributeDetails for a database and
1448 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1449 exist for the database.
1451 If the database doesn't exist globally (in TargetInfo) an
1452 AttributeSetInfo must be added (globally).