2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.27 2002-04-15 09:07:10 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);
439 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
441 if (!zei->data1_target)
444 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
445 nmem_destroy (zei->nmem);
449 data1_pr_tree (zei->dh, zei->data1_target, stderr);
451 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
453 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
456 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
461 node_list = data1_search_tag (zei->dh, node_zebra->child,
464 np = node_list->child;
466 for (; np; np = np->next)
468 data1_node *node_name = NULL;
469 data1_node *node_id = NULL;
470 data1_node *node_aid = NULL;
472 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
474 for (np2 = np->child; np2; np2 = np2->next)
476 if (np2->which != DATA1N_tag)
478 if (!strcmp (np2->u.tag.tag, "name"))
479 node_name = np2->child;
480 else if (!strcmp (np2->u.tag.tag, "id"))
481 node_id = np2->child;
482 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
483 node_aid = np2->child;
485 assert (node_id && node_name && node_aid);
487 *zdip = (struct zebDatabaseInfoB *)
488 nmem_malloc (zei->nmem, sizeof(**zdip));
489 (*zdip)->readFlag = 1;
491 (*zdip)->data1_database = NULL;
492 (*zdip)->recordCount = 0;
493 (*zdip)->recordBytes = 0;
494 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
496 (*zdip)->databaseName = (char *)
497 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
498 memcpy ((*zdip)->databaseName, node_name->u.data.data,
499 node_name->u.data.len);
500 (*zdip)->databaseName[node_name->u.data.len] = '\0';
501 (*zdip)->sysno = atoi_n (node_id->u.data.data,
502 node_id->u.data.len);
503 (*zdip)->attributeDetails = (zebAttributeDetails)
504 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
505 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
506 node_aid->u.data.len);
507 (*zdip)->attributeDetails->readFlag = 1;
508 (*zdip)->attributeDetails->dirty = 0;
509 (*zdip)->attributeDetails->SUInfo = NULL;
511 zdip = &(*zdip)->next;
515 np = data1_search_tag (zei->dh, node_zebra->child,
518 assert (np && np->which == DATA1N_data);
519 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
521 np = data1_search_tag (zei->dh, node_zebra->child,
524 assert (np && np->which == DATA1N_data);
525 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
530 else /* create initial targetInfo */
532 data1_node *node_tgtinfo;
541 data1_read_sgml (zei->dh, zei->nmem,
542 "<explain><targetInfo>TargetInfo\n"
544 "<namedResultSets>1</>\n"
545 "<multipleDBSearch>1</>\n"
546 "<nicknames><name>Zebra</></>\n"
548 if (!zei->data1_target)
550 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
551 nmem_destroy (zei->nmem);
554 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
556 assert (node_tgtinfo);
558 zebraExplain_initCommonInfo (zei, node_tgtinfo);
559 zebraExplain_initAccessInfo (zei, node_tgtinfo);
561 /* write now because we want to be sure about the sysno */
562 trec = rec_new (records);
563 trec->info[recInfo_fileType] =
564 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
565 trec->info[recInfo_databaseName] =
566 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
568 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
569 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
570 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
571 trec->size[recInfo_storeData] = sgml_len;
573 rec_put (records, &trec);
577 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
579 if (!zei->categoryList->dirty)
581 struct zebraCategoryListInfo *zcl = zei->categoryList;
585 zcl->data1_categoryList =
586 data1_read_sgml (zei->dh, zei->nmem,
587 "<explain><categoryList>CategoryList\n"
590 if (zcl->data1_categoryList)
592 assert (zcl->data1_categoryList->child);
593 node_cl = data1_search_tag (zei->dh,
594 zcl->data1_categoryList->child,
597 zebraExplain_initCommonInfo (zei, node_cl);
604 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
605 zebAttributeDetails zad)
608 struct zebSUInfoB **zsuip = &zad->SUInfo;
609 data1_node *node_adinfo, *node_zebra, *node_list, *np;
612 rec = rec_get (zei->records, zad->sysno);
614 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
616 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
618 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
620 node_list = data1_search_tag (zei->dh, node_zebra->child,
622 for (np = node_list->child; np; np = np->next)
624 data1_node *node_set = NULL;
625 data1_node *node_use = NULL;
626 data1_node *node_ordinal = NULL;
631 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
633 for (np2 = np->child; np2; np2 = np2->next)
635 if (np2->which != DATA1N_tag || !np2->child ||
636 np2->child->which != DATA1N_data)
638 if (!strcmp (np2->u.tag.tag, "set"))
639 node_set = np2->child;
640 else if (!strcmp (np2->u.tag.tag, "use"))
641 node_use = np2->child;
642 else if (!strcmp (np2->u.tag.tag, "ordinal"))
643 node_ordinal = np2->child;
645 assert (node_set && node_use && node_ordinal);
647 oid_str_len = node_set->u.data.len;
648 if (oid_str_len >= (int) sizeof(oid_str))
649 oid_str_len = sizeof(oid_str)-1;
650 memcpy (oid_str, node_set->u.data.data, oid_str_len);
651 oid_str[oid_str_len] = '\0';
653 *zsuip = (struct zebSUInfoB *)
654 nmem_malloc (zei->nmem, sizeof(**zsuip));
655 (*zsuip)->info.set = oid_getvalbyname (oid_str);
657 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
658 node_use->u.data.len);
659 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
660 node_ordinal->u.data.len);
661 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
662 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
663 zsuip = &(*zsuip)->next;
670 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
671 struct zebDatabaseInfoB *zdi)
674 data1_node *node_dbinfo, *node_zebra, *np;
677 rec = rec_get (zei->records, zdi->sysno);
679 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
681 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
683 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
685 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
688 && (np = data1_search_tag (zei->dh, node_zebra->child,
690 && np->child && np->child->which == DATA1N_data)
691 zdi->recordBytes = atoi_n (np->child->u.data.data,
692 np->child->u.data.len);
693 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
695 (np = data1_search_tag (zei->dh, np->child,
696 "recordCountActual")) &&
697 np->child->which == DATA1N_data)
699 zdi->recordCount = atoi_n (np->child->u.data.data,
700 np->child->u.data.len);
706 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
708 struct zebDatabaseInfoB *zdi;
709 const char *database_n = strrchr (database, '/');
714 database_n = database;
717 if (zei->curDatabaseInfo &&
718 !strcmp (zei->curDatabaseInfo->databaseName, database))
720 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
722 if (!strcmp (zdi->databaseName, database_n))
728 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
733 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
735 zebraExplain_readDatabase (zei, zdi);
737 if (zdi->attributeDetails->readFlag)
740 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
742 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
744 zei->curDatabaseInfo = zdi;
748 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
750 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
752 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
753 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
754 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
757 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
759 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
761 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
764 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
766 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
767 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
768 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
771 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
772 zebAccessInfo accessInfo)
774 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
780 if ((p = accessInfo->attributeSetIds))
782 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
783 for (; p; p = p->next)
784 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
786 if ((p = accessInfo->schemas))
788 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
789 for (; p; p = p->next)
790 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
794 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
795 int explain_database)
797 struct zebDatabaseInfoB *zdi;
798 data1_node *node_dbinfo, *node_adinfo;
799 const char *database_n = strrchr (database, '/');
804 database_n = database;
807 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
810 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
812 if (!strcmp (zdi->databaseName, database_n))
817 /* it's new really. make it */
818 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
819 zdi->next = zei->databaseInfo;
820 zei->databaseInfo = zdi;
822 zdi->recordCount = 0;
823 zdi->recordBytes = 0;
825 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
827 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
832 zdi->data1_database =
833 data1_read_sgml (zei->dh, zei->nmem,
834 "<explain><databaseInfo>DatabaseInfo\n"
836 if (!zdi->data1_database)
839 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
841 assert (node_dbinfo);
843 zebraExplain_initCommonInfo (zei, node_dbinfo);
844 zebraExplain_initAccessInfo (zei, node_dbinfo);
846 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
847 database, zei->nmem);
849 if (explain_database)
850 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
853 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
856 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
860 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
864 zei->curDatabaseInfo = zdi;
866 zdi->attributeDetails = (zebAttributeDetails)
867 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
868 zdi->attributeDetails->readFlag = 0;
869 zdi->attributeDetails->sysno = 0;
870 zdi->attributeDetails->dirty = 1;
871 zdi->attributeDetails->SUInfo = NULL;
872 zdi->attributeDetails->data1_tree =
873 data1_read_sgml (zei->dh, zei->nmem,
874 "<explain><attributeDetails>AttributeDetails\n"
878 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
880 assert (node_adinfo);
882 zebraExplain_initCommonInfo (zei, node_adinfo);
887 static void writeAttributeValueDetails (ZebraExplainInfo zei,
888 zebAttributeDetails zad,
889 data1_node *node_atvs, data1_attset *attset)
892 struct zebSUInfoB *zsui;
893 int set_ordinal = attset->reference;
894 data1_attset_child *c;
896 for (c = attset->children; c; c = c->next)
897 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
898 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
900 data1_node *node_attvalue, *node_value;
901 if (set_ordinal != zsui->info.set)
903 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
905 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
907 data1_add_tagdata_int (zei->dh, node_value, "numeric",
908 zsui->info.use, zei->nmem);
912 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
913 struct zebraCategoryListInfo *zcl,
920 data1_node *node_ci, *node_categoryList;
922 static char *category[] = {
934 node_categoryList = zcl->data1_categoryList;
937 logf (LOG_LOG, "zebraExplain_writeCategoryList");
940 drec = createRecord (zei->records, &sysno);
942 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
945 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
948 for (i = 0; category[i]; i++)
950 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
951 "category", zei->nmem);
953 data1_add_tagdata_text (zei->dh, node_cat, "name",
954 category[i], zei->nmem);
956 /* extract *searchable* keys from it. We do this here, because
957 record count, etc. is affected */
959 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
961 /* convert to "SGML" and write it */
963 data1_pr_tree (zei->dh, node_categoryList, stderr);
965 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
966 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
967 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
968 drec->size[recInfo_storeData] = sgml_len;
970 rec_put (zei->records, &drec);
973 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
974 zebAttributeDetails zad,
975 const char *databaseName,
981 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
982 struct zebSUInfoB *zsui;
990 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
993 drec = createRecord (zei->records, &zad->sysno);
994 assert (zad->data1_tree);
995 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
997 zebraExplain_updateCommonInfo (zei, node_adinfo);
999 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
1000 databaseName, zei->nmem);
1002 /* extract *searchable* keys from it. We do this here, because
1003 record count, etc. is affected */
1005 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1007 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
1008 "attributesBySet", zei->nmem);
1012 data1_node *node_asd;
1013 data1_attset *attset;
1014 int set_ordinal = -1;
1015 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1017 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1018 && zsui->info.set > set_min)
1019 set_ordinal = zsui->info.set;
1021 if (set_ordinal < 0)
1023 set_min = set_ordinal;
1024 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1025 "attributeSetDetails", zei->nmem);
1027 attset = data1_attset_search_id (zei->dh, set_ordinal);
1030 zebraExplain_loadAttsets (zei->dh, zei->res);
1031 attset = data1_attset_search_id (zei->dh, set_ordinal);
1038 oe.proto = PROTO_Z3950;
1039 oe.oclass = CLASS_ATTSET;
1040 oe.value = (enum oid_value) set_ordinal;
1042 if (oid_ent_to_oid (&oe, oid))
1044 data1_node *node_abt, *node_atd, *node_atvs;
1045 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1048 node_abt = data1_add_tag (zei->dh, node_asd,
1049 "attributesByType", zei->nmem);
1050 node_atd = data1_add_tag (zei->dh, node_abt,
1051 "attributeTypeDetails", zei->nmem);
1052 data1_add_tagdata_int (zei->dh, node_atd,
1053 "type", 1, zei->nmem);
1054 node_atvs = data1_add_tag (zei->dh, node_atd,
1055 "attributeValues", zei->nmem);
1056 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1060 /* zebra info (private) */
1061 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1062 "zebraInfo", zei->nmem);
1063 node_list = data1_make_tag (zei->dh, node_zebra,
1064 "attrlist", zei->nmem);
1065 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1067 struct oident oident;
1069 data1_node *node_attr;
1071 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1073 oident.proto = PROTO_Z3950;
1074 oident.oclass = CLASS_ATTSET;
1075 oident.value = (enum oid_value) zsui->info.set;
1076 oid_ent_to_oid (&oident, oid);
1078 data1_add_tagdata_text (zei->dh, node_attr, "set",
1079 oident.desc, zei->nmem);
1080 data1_add_tagdata_int (zei->dh, node_attr, "use",
1081 zsui->info.use, zei->nmem);
1082 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1083 zsui->info.ordinal, zei->nmem);
1085 /* convert to "SGML" and write it */
1087 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1089 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1091 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1092 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1093 drec->size[recInfo_storeData] = sgml_len;
1095 rec_put (zei->records, &drec);
1098 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1099 struct zebDatabaseInfoB *zdi,
1105 data1_node *node_dbinfo, *node_count, *node_zebra;
1112 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1114 drec = createRecord (zei->records, &zdi->sysno);
1115 assert (zdi->data1_database);
1116 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1119 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1120 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1122 /* extract *searchable* keys from it. We do this here, because
1123 record count, etc. is affected */
1125 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1127 node_count = data1_make_tag (zei->dh, node_dbinfo,
1128 "recordCount", zei->nmem);
1129 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1130 zdi->recordCount, zei->nmem);
1132 /* zebra info (private) */
1133 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1134 "zebraInfo", zei->nmem);
1135 data1_add_tagdata_int (zei->dh, node_zebra,
1136 "recordBytes", zdi->recordBytes, zei->nmem);
1137 /* convert to "SGML" and write it */
1139 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1141 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1143 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1144 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1145 drec->size[recInfo_storeData] = sgml_len;
1147 rec_put (zei->records, &drec);
1150 static void writeAttributeValues (ZebraExplainInfo zei,
1151 data1_node *node_values,
1152 data1_attset *attset)
1155 data1_attset_child *c;
1160 for (c = attset->children; c; c = c->next)
1161 writeAttributeValues (zei, node_values, c->child);
1162 for (atts = attset->atts; atts; atts = atts->next)
1164 data1_node *node_value;
1166 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1168 data1_add_tagdata_text (zei->dh, node_value, "name",
1169 atts->name, zei->nmem);
1170 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1171 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1172 atts->value, zei->nmem);
1177 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1184 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1185 data1_node *node_values;
1186 struct oident *entp;
1187 struct data1_attset *attset = NULL;
1189 if ((entp = oid_getentbyoid (o->oid)))
1190 attset = data1_attset_search_id (zei->dh, entp->value);
1193 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1194 attset ? attset->name : "<unknown>");
1197 drec = createRecord (zei->records, &o->sysno);
1199 data1_read_sgml (zei->dh, zei->nmem,
1200 "<explain><attributeSetInfo>AttributeSetInfo\n"
1203 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1204 "attributeSetInfo");
1206 zebraExplain_initCommonInfo (zei, node_attinfo);
1207 zebraExplain_updateCommonInfo (zei, node_attinfo);
1209 data1_add_tagdata_oid (zei->dh, node_attinfo,
1210 "oid", o->oid, zei->nmem);
1211 if (attset && attset->name)
1212 data1_add_tagdata_text (zei->dh, node_attinfo,
1213 "name", attset->name, zei->nmem);
1215 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1216 "attributes", zei->nmem);
1217 node_atttype = data1_make_tag (zei->dh, node_attributes,
1218 "attributeType", zei->nmem);
1219 data1_add_tagdata_text (zei->dh, node_atttype,
1220 "name", "Use", zei->nmem);
1221 data1_add_tagdata_text (zei->dh, node_atttype,
1222 "description", "Use Attribute", zei->nmem);
1223 data1_add_tagdata_int (zei->dh, node_atttype,
1224 "type", 1, zei->nmem);
1225 node_values = data1_add_tag (zei->dh, node_atttype,
1226 "attributeValues", zei->nmem);
1228 writeAttributeValues (zei, node_values, attset);
1230 /* extract *searchable* keys from it. We do this here, because
1231 record count, etc. is affected */
1233 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1234 /* convert to "SGML" and write it */
1236 data1_pr_tree (zei->dh, node_root, stderr);
1238 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1239 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1240 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1241 drec->size[recInfo_storeData] = sgml_len;
1243 rec_put (zei->records, &drec);
1246 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1248 struct zebDatabaseInfoB *zdi;
1249 data1_node *node_tgtinfo, *node_list, *node_zebra;
1258 trec = rec_get (zei->records, 1);
1259 xfree (trec->info[recInfo_storeData]);
1261 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1263 assert (node_tgtinfo);
1265 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1266 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1268 /* convert to "SGML" and write it */
1270 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1272 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1273 "zebraInfo", zei->nmem);
1274 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1275 ZEBRAVER, zei->nmem);
1276 node_list = data1_add_tag (zei->dh, node_zebra,
1277 "databaseList", zei->nmem);
1278 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1280 data1_node *node_db;
1281 node_db = data1_add_tag (zei->dh, node_list,
1282 "database", zei->nmem);
1283 data1_add_tagdata_text (zei->dh, node_db, "name",
1284 zdi->databaseName, zei->nmem);
1285 data1_add_tagdata_int (zei->dh, node_db, "id",
1286 zdi->sysno, zei->nmem);
1287 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1288 zdi->attributeDetails->sysno, zei->nmem);
1290 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1291 zei->ordinalSU, zei->nmem);
1293 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1294 zei->runNumber, zei->nmem);
1297 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1299 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1301 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1302 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1303 trec->size[recInfo_storeData] = sgml_len;
1305 rec_put (zei->records, &trec);
1308 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1310 struct zebSUInfoB *zsui;
1312 assert (zei->curDatabaseInfo);
1313 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1314 zsui; zsui=zsui->next)
1315 if (zsui->info.use == use && zsui->info.set == set)
1316 return zsui->info.ordinal;
1320 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1321 const char **db, int *set, int *use)
1323 struct zebDatabaseInfoB *zdb;
1324 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1326 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1327 for ( ;zsui; zsui = zsui->next)
1328 if (zsui->info.ordinal == ord)
1330 *db = zdb->databaseName;
1331 *set = zsui->info.set;
1332 *use = zsui->info.use;
1339 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1340 zebAccessObject *op,
1345 for (ao = *op; ao; ao = ao->next)
1346 if (!oid_oidcmp (oid, ao->oid))
1350 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1353 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1360 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1365 oe.proto = PROTO_Z3950;
1366 oe.oclass = CLASS_ATTSET;
1367 oe.value = (enum oid_value) set;
1369 if (oid_ent_to_oid (&oe, oid))
1371 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1372 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1373 accessInfo->attributeSetIds, oid);
1377 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1379 struct zebSUInfoB *zsui;
1381 assert (zei->curDatabaseInfo);
1382 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1383 zsui; zsui=zsui->next)
1384 if (zsui->info.use == use && zsui->info.set == set)
1386 zebraExplain_addAttributeSet (zei, set);
1387 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1388 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1389 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1390 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1392 zsui->info.set = set;
1393 zsui->info.use = use;
1394 zsui->info.ordinal = (zei->ordinalSU)++;
1395 return zsui->info.ordinal;
1398 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1400 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1401 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1402 accessInfo->schemas, oid);
1405 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1407 assert (zei->curDatabaseInfo);
1411 zei->curDatabaseInfo->recordBytes += adjust_num;
1412 zei->curDatabaseInfo->dirty = 1;
1416 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1418 assert (zei->curDatabaseInfo);
1422 zei->curDatabaseInfo->recordCount += adjust_num;
1423 zei->curDatabaseInfo->dirty = 1;
1427 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1431 return zei->runNumber += adjust_num;
1434 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1436 RecordAttr *recordAttr;
1438 if (rec->info[recInfo_attr])
1439 return (RecordAttr *) rec->info[recInfo_attr];
1440 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1441 rec->info[recInfo_attr] = (char *) recordAttr;
1442 rec->size[recInfo_attr] = sizeof(*recordAttr);
1444 recordAttr->recordSize = 0;
1445 recordAttr->recordOffset = 0;
1446 recordAttr->runNumber = zei->runNumber;
1450 static void att_loadset(void *p, const char *n, const char *name)
1452 data1_handle dh = (data1_handle) p;
1453 if (!data1_get_attset (dh, name))
1454 logf (LOG_WARN, "Directive attset failed for %s", name);
1457 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1459 res_trav(res, "attset", dh, att_loadset);
1463 zebraExplain_addSU adds to AttributeDetails for a database and
1464 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1465 exist for the database.
1467 If the database doesn't exist globally (in TargetInfo) an
1468 AttributeSetInfo must be added (globally).