2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.25 2002-04-04 14:14:13 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;
705 const char *database_n = strrchr (database, '/');
710 database_n = database;
713 if (zei->curDatabaseInfo &&
714 !strcmp (zei->curDatabaseInfo->databaseName, database))
716 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
718 if (!strcmp (zdi->databaseName, database_n))
724 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
729 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
731 zebraExplain_readDatabase (zei, zdi);
733 if (zdi->attributeDetails->readFlag)
736 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
738 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
740 zei->curDatabaseInfo = zdi;
744 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
746 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
748 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
749 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
750 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
753 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
755 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
757 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
760 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
762 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
763 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
764 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
767 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
768 zebAccessInfo accessInfo)
770 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
776 if ((p = accessInfo->attributeSetIds))
778 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
779 for (; p; p = p->next)
780 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
782 if ((p = accessInfo->schemas))
784 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
785 for (; p; p = p->next)
786 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
790 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
791 int explain_database)
793 struct zebDatabaseInfoB *zdi;
794 data1_node *node_dbinfo, *node_adinfo;
795 const char *database_n = strrchr (database, '/');
800 database_n = database;
803 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
806 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
808 if (!strcmp (zdi->databaseName, database_n))
813 /* it's new really. make it */
814 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
815 zdi->next = zei->databaseInfo;
816 zei->databaseInfo = zdi;
818 zdi->recordCount = 0;
819 zdi->recordBytes = 0;
821 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
823 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
828 zdi->data1_database =
829 data1_read_sgml (zei->dh, zei->nmem,
830 "<explain><databaseInfo>DatabaseInfo\n"
832 if (!zdi->data1_database)
835 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
837 assert (node_dbinfo);
839 zebraExplain_initCommonInfo (zei, node_dbinfo);
840 zebraExplain_initAccessInfo (zei, node_dbinfo);
842 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
843 database, zei->nmem);
845 if (explain_database)
846 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
849 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
852 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
856 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
860 zei->curDatabaseInfo = zdi;
862 zdi->attributeDetails = (zebAttributeDetails)
863 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
864 zdi->attributeDetails->readFlag = 0;
865 zdi->attributeDetails->sysno = 0;
866 zdi->attributeDetails->dirty = 1;
867 zdi->attributeDetails->SUInfo = NULL;
868 zdi->attributeDetails->data1_tree =
869 data1_read_sgml (zei->dh, zei->nmem,
870 "<explain><attributeDetails>AttributeDetails\n"
874 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
876 assert (node_adinfo);
878 zebraExplain_initCommonInfo (zei, node_adinfo);
883 static void writeAttributeValueDetails (ZebraExplainInfo zei,
884 zebAttributeDetails zad,
885 data1_node *node_atvs, data1_attset *attset)
888 struct zebSUInfoB *zsui;
889 int set_ordinal = attset->reference;
890 data1_attset_child *c;
892 for (c = attset->children; c; c = c->next)
893 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
894 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
896 data1_node *node_attvalue, *node_value;
897 if (set_ordinal != zsui->info.set)
899 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
901 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
903 data1_add_tagdata_int (zei->dh, node_value, "numeric",
904 zsui->info.use, zei->nmem);
908 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
909 struct zebraCategoryListInfo *zcl,
916 data1_node *node_ci, *node_categoryList;
918 static char *category[] = {
930 node_categoryList = zcl->data1_categoryList;
933 logf (LOG_LOG, "zebraExplain_writeCategoryList");
936 drec = createRecord (zei->records, &sysno);
938 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
941 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
944 for (i = 0; category[i]; i++)
946 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
947 "category", zei->nmem);
949 data1_add_tagdata_text (zei->dh, node_cat, "name",
950 category[i], zei->nmem);
952 /* extract *searchable* keys from it. We do this here, because
953 record count, etc. is affected */
955 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
957 /* convert to "SGML" and write it */
959 data1_pr_tree (zei->dh, node_categoryList, stderr);
961 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
962 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
963 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
964 drec->size[recInfo_storeData] = sgml_len;
966 rec_put (zei->records, &drec);
969 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
970 zebAttributeDetails zad,
971 const char *databaseName,
977 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
978 struct zebSUInfoB *zsui;
986 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
989 drec = createRecord (zei->records, &zad->sysno);
990 assert (zad->data1_tree);
991 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
993 zebraExplain_updateCommonInfo (zei, node_adinfo);
995 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
996 databaseName, zei->nmem);
998 /* extract *searchable* keys from it. We do this here, because
999 record count, etc. is affected */
1001 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1003 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
1004 "attributesBySet", zei->nmem);
1008 data1_node *node_asd;
1009 data1_attset *attset;
1010 int set_ordinal = -1;
1011 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1013 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1014 && zsui->info.set > set_min)
1015 set_ordinal = zsui->info.set;
1017 if (set_ordinal < 0)
1019 set_min = set_ordinal;
1020 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1021 "attributeSetDetails", zei->nmem);
1023 attset = data1_attset_search_id (zei->dh, set_ordinal);
1026 zebraExplain_loadAttsets (zei->dh, zei->res);
1027 attset = data1_attset_search_id (zei->dh, set_ordinal);
1034 oe.proto = PROTO_Z3950;
1035 oe.oclass = CLASS_ATTSET;
1036 oe.value = (enum oid_value) set_ordinal;
1038 if (oid_ent_to_oid (&oe, oid))
1040 data1_node *node_abt, *node_atd, *node_atvs;
1041 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1044 node_abt = data1_add_tag (zei->dh, node_asd,
1045 "attributesByType", zei->nmem);
1046 node_atd = data1_add_tag (zei->dh, node_abt,
1047 "attributeTypeDetails", zei->nmem);
1048 data1_add_tagdata_int (zei->dh, node_atd,
1049 "type", 1, zei->nmem);
1050 node_atvs = data1_add_tag (zei->dh, node_atd,
1051 "attributeValues", zei->nmem);
1052 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1056 /* zebra info (private) */
1057 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1058 "zebraInfo", zei->nmem);
1059 node_list = data1_make_tag (zei->dh, node_zebra,
1060 "attrlist", zei->nmem);
1061 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1063 struct oident oident;
1065 data1_node *node_attr;
1067 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1069 oident.proto = PROTO_Z3950;
1070 oident.oclass = CLASS_ATTSET;
1071 oident.value = (enum oid_value) zsui->info.set;
1072 oid_ent_to_oid (&oident, oid);
1074 data1_add_tagdata_text (zei->dh, node_attr, "set",
1075 oident.desc, zei->nmem);
1076 data1_add_tagdata_int (zei->dh, node_attr, "use",
1077 zsui->info.use, zei->nmem);
1078 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1079 zsui->info.ordinal, zei->nmem);
1081 /* convert to "SGML" and write it */
1083 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1085 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1087 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1088 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1089 drec->size[recInfo_storeData] = sgml_len;
1091 rec_put (zei->records, &drec);
1094 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1095 struct zebDatabaseInfoB *zdi,
1101 data1_node *node_dbinfo, *node_count, *node_zebra;
1108 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1110 drec = createRecord (zei->records, &zdi->sysno);
1111 assert (zdi->data1_database);
1112 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1115 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1116 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1118 /* extract *searchable* keys from it. We do this here, because
1119 record count, etc. is affected */
1121 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1123 node_count = data1_make_tag (zei->dh, node_dbinfo,
1124 "recordCount", zei->nmem);
1125 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1126 zdi->recordCount, zei->nmem);
1128 /* zebra info (private) */
1129 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1130 "zebraInfo", zei->nmem);
1131 data1_add_tagdata_int (zei->dh, node_zebra,
1132 "recordBytes", zdi->recordBytes, zei->nmem);
1133 /* convert to "SGML" and write it */
1135 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1137 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1139 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1140 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1141 drec->size[recInfo_storeData] = sgml_len;
1143 rec_put (zei->records, &drec);
1146 static void writeAttributeValues (ZebraExplainInfo zei,
1147 data1_node *node_values,
1148 data1_attset *attset)
1151 data1_attset_child *c;
1156 for (c = attset->children; c; c = c->next)
1157 writeAttributeValues (zei, node_values, c->child);
1158 for (atts = attset->atts; atts; atts = atts->next)
1160 data1_node *node_value;
1162 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1164 data1_add_tagdata_text (zei->dh, node_value, "name",
1165 atts->name, zei->nmem);
1166 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1167 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1168 atts->value, zei->nmem);
1173 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1180 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1181 data1_node *node_values;
1182 struct oident *entp;
1183 struct data1_attset *attset = NULL;
1185 if ((entp = oid_getentbyoid (o->oid)))
1186 attset = data1_attset_search_id (zei->dh, entp->value);
1189 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1190 attset ? attset->name : "<unknown>");
1193 drec = createRecord (zei->records, &o->sysno);
1195 data1_read_sgml (zei->dh, zei->nmem,
1196 "<explain><attributeSetInfo>AttributeSetInfo\n"
1199 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1200 "attributeSetInfo");
1202 zebraExplain_initCommonInfo (zei, node_attinfo);
1203 zebraExplain_updateCommonInfo (zei, node_attinfo);
1205 data1_add_tagdata_oid (zei->dh, node_attinfo,
1206 "oid", o->oid, zei->nmem);
1207 if (attset && attset->name)
1208 data1_add_tagdata_text (zei->dh, node_attinfo,
1209 "name", attset->name, zei->nmem);
1211 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1212 "attributes", zei->nmem);
1213 node_atttype = data1_make_tag (zei->dh, node_attributes,
1214 "attributeType", zei->nmem);
1215 data1_add_tagdata_text (zei->dh, node_atttype,
1216 "name", "Use", zei->nmem);
1217 data1_add_tagdata_text (zei->dh, node_atttype,
1218 "description", "Use Attribute", zei->nmem);
1219 data1_add_tagdata_int (zei->dh, node_atttype,
1220 "type", 1, zei->nmem);
1221 node_values = data1_add_tag (zei->dh, node_atttype,
1222 "attributeValues", zei->nmem);
1224 writeAttributeValues (zei, node_values, attset);
1226 /* extract *searchable* keys from it. We do this here, because
1227 record count, etc. is affected */
1229 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1230 /* convert to "SGML" and write it */
1232 data1_pr_tree (zei->dh, node_root, stderr);
1234 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1235 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1236 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1237 drec->size[recInfo_storeData] = sgml_len;
1239 rec_put (zei->records, &drec);
1242 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1244 struct zebDatabaseInfoB *zdi;
1245 data1_node *node_tgtinfo, *node_list, *node_zebra;
1254 trec = rec_get (zei->records, 1);
1255 xfree (trec->info[recInfo_storeData]);
1257 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1259 assert (node_tgtinfo);
1261 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1262 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1264 /* convert to "SGML" and write it */
1266 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1268 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1269 "zebraInfo", zei->nmem);
1270 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1271 ZEBRAVER, zei->nmem);
1272 node_list = data1_add_tag (zei->dh, node_zebra,
1273 "databaseList", zei->nmem);
1274 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1276 data1_node *node_db;
1277 node_db = data1_add_tag (zei->dh, node_list,
1278 "database", zei->nmem);
1279 data1_add_tagdata_text (zei->dh, node_db, "name",
1280 zdi->databaseName, zei->nmem);
1281 data1_add_tagdata_int (zei->dh, node_db, "id",
1282 zdi->sysno, zei->nmem);
1283 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1284 zdi->attributeDetails->sysno, zei->nmem);
1286 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1287 zei->ordinalSU, zei->nmem);
1289 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1290 zei->runNumber, zei->nmem);
1293 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1295 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1297 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1298 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1299 trec->size[recInfo_storeData] = sgml_len;
1301 rec_put (zei->records, &trec);
1304 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1306 struct zebSUInfoB *zsui;
1308 assert (zei->curDatabaseInfo);
1309 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1310 zsui; zsui=zsui->next)
1311 if (zsui->info.use == use && zsui->info.set == set)
1312 return zsui->info.ordinal;
1316 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1317 const char **db, int *set, int *use)
1319 struct zebDatabaseInfoB *zdb;
1320 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1322 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1323 for ( ;zsui; zsui = zsui->next)
1324 if (zsui->info.ordinal == ord)
1326 *db = zdb->databaseName;
1327 *set = zsui->info.set;
1328 *use = zsui->info.use;
1335 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1336 zebAccessObject *op,
1341 for (ao = *op; ao; ao = ao->next)
1342 if (!oid_oidcmp (oid, ao->oid))
1346 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1349 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1356 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1361 oe.proto = PROTO_Z3950;
1362 oe.oclass = CLASS_ATTSET;
1363 oe.value = (enum oid_value) set;
1365 if (oid_ent_to_oid (&oe, oid))
1367 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1368 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1369 accessInfo->attributeSetIds, oid);
1373 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1375 struct zebSUInfoB *zsui;
1377 assert (zei->curDatabaseInfo);
1378 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1379 zsui; zsui=zsui->next)
1380 if (zsui->info.use == use && zsui->info.set == set)
1382 zebraExplain_addAttributeSet (zei, set);
1383 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1384 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1385 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1386 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1388 zsui->info.set = set;
1389 zsui->info.use = use;
1390 zsui->info.ordinal = (zei->ordinalSU)++;
1391 return zsui->info.ordinal;
1394 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1396 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1397 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1398 accessInfo->schemas, oid);
1401 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1403 assert (zei->curDatabaseInfo);
1407 zei->curDatabaseInfo->recordBytes += adjust_num;
1408 zei->curDatabaseInfo->dirty = 1;
1412 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1414 assert (zei->curDatabaseInfo);
1418 zei->curDatabaseInfo->recordCount += adjust_num;
1419 zei->curDatabaseInfo->dirty = 1;
1423 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1427 return zei->runNumber += adjust_num;
1430 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1432 RecordAttr *recordAttr;
1434 if (rec->info[recInfo_attr])
1435 return (RecordAttr *) rec->info[recInfo_attr];
1436 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1437 rec->info[recInfo_attr] = (char *) recordAttr;
1438 rec->size[recInfo_attr] = sizeof(*recordAttr);
1440 recordAttr->recordSize = 0;
1441 recordAttr->recordOffset = 0;
1442 recordAttr->runNumber = zei->runNumber;
1446 static void att_loadset(void *p, const char *n, const char *name)
1448 data1_handle dh = (data1_handle) p;
1449 if (!data1_get_attset (dh, name))
1450 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1453 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1455 res_trav(res, "attset", dh, att_loadset);
1459 zebraExplain_addSU adds to AttributeDetails for a database and
1460 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1461 exist for the database.
1463 If the database doesn't exist globally (in TargetInfo) an
1464 AttributeSetInfo must be added (globally).