2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.23 2002-02-20 17:30:01 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)
272 zei->updateHandle = handle;
275 struct zebDatabaseInfoB *zdi;
278 /* write each database info record */
279 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
281 zebraExplain_writeDatabase (zei, zdi, 1);
282 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
283 zdi->databaseName, 1);
285 zebraExplain_writeTarget (zei, 1);
286 zebraExplain_writeCategoryList (zei,
289 assert (zei->accessInfo);
290 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
292 zebraExplain_writeAttributeSet (zei, o, 1);
293 for (o = zei->accessInfo->schemas; o; o = o->next)
296 /* zebraExplain_writeSchema (zei, o, 1); */
299 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
301 zebraExplain_writeDatabase (zei, zdi, 0);
302 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
303 zdi->databaseName, 0);
305 zebraExplain_writeTarget (zei, 0);
309 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag)
312 logf (LOG_LOG, "zebraExplain_close wr=%d", writeFlag);
316 zebraExplain_flush (zei, writeFlag, zei->updateHandle);
317 nmem_destroy (zei->nmem);
320 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
325 for (np = n->child; np; np = np->next)
332 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
334 len = np->child->u.data.len;
337 memcpy (str, np->child->u.data.data, len);
340 oid = odr_getoidbystr_nmem (zei->nmem, str);
342 for (ao = *op; ao; ao = ao->next)
343 if (!oid_oidcmp (oid, ao->oid))
350 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
360 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
361 zebAccessInfo *accessInfo)
367 *accessInfo = (zebAccessInfo)
368 nmem_malloc (zei->nmem, sizeof(**accessInfo));
369 (*accessInfo)->attributeSetIds = NULL;
370 (*accessInfo)->schemas = NULL;
374 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
376 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
377 zebraExplain_mergeOids (zei, np,
378 &(*accessInfo)->attributeSetIds);
379 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
380 zebraExplain_mergeOids (zei, np,
381 &(*accessInfo)->schemas);
385 ZebraExplainInfo zebraExplain_open (
386 Records records, data1_handle dh,
390 int (*updateFunc)(void *handle, Record drec, data1_node *n))
393 ZebraExplainInfo zei;
394 struct zebDatabaseInfoB **zdip;
397 NMEM nmem = nmem_create ();
400 logf (LOG_LOG, "zebraExplain_open wr=%d", writeFlag);
402 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
403 zei->updateHandle = updateHandle;
404 zei->updateFunc = updateFunc;
406 zei->curDatabaseInfo = NULL;
407 zei->records = records;
412 zei->categoryList = (struct zebraCategoryListInfo *)
413 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
414 zei->categoryList->sysno = 0;
415 zei->categoryList->dirty = 0;
416 zei->categoryList->data1_categoryList = NULL;
419 tm = localtime (&our_time);
420 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
421 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
422 tm->tm_hour, tm->tm_min, tm->tm_sec);
424 zdip = &zei->databaseInfo;
425 trec = rec_get (records, 1); /* get "root" record */
430 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
431 if (trec) /* targetInfo already exists ... */
433 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
435 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
436 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
438 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
439 nmem_destroy (zei->nmem);
443 data1_pr_tree (zei->dh, zei->data1_target, stderr);
445 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
447 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
450 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
455 node_list = data1_search_tag (zei->dh, node_zebra->child,
458 np = node_list->child;
460 for (; np; np = np->next)
462 data1_node *node_name = NULL;
463 data1_node *node_id = NULL;
464 data1_node *node_aid = NULL;
466 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
468 for (np2 = np->child; np2; np2 = np2->next)
470 if (np2->which != DATA1N_tag)
472 if (!strcmp (np2->u.tag.tag, "name"))
473 node_name = np2->child;
474 else if (!strcmp (np2->u.tag.tag, "id"))
475 node_id = np2->child;
476 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
477 node_aid = np2->child;
479 assert (node_id && node_name && node_aid);
481 *zdip = (struct zebDatabaseInfoB *)
482 nmem_malloc (zei->nmem, sizeof(**zdip));
483 (*zdip)->readFlag = 1;
485 (*zdip)->data1_database = NULL;
486 (*zdip)->recordCount = 0;
487 (*zdip)->recordBytes = 0;
488 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
490 (*zdip)->databaseName = (char *)
491 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
492 memcpy ((*zdip)->databaseName, node_name->u.data.data,
493 node_name->u.data.len);
494 (*zdip)->databaseName[node_name->u.data.len] = '\0';
495 (*zdip)->sysno = atoi_n (node_id->u.data.data,
496 node_id->u.data.len);
497 (*zdip)->attributeDetails = (zebAttributeDetails)
498 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
499 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
500 node_aid->u.data.len);
501 (*zdip)->attributeDetails->readFlag = 1;
502 (*zdip)->attributeDetails->dirty = 0;
503 (*zdip)->attributeDetails->SUInfo = NULL;
505 zdip = &(*zdip)->next;
509 np = data1_search_tag (zei->dh, node_zebra->child,
512 assert (np && np->which == DATA1N_data);
513 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
515 np = data1_search_tag (zei->dh, node_zebra->child,
518 assert (np && np->which == DATA1N_data);
519 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
524 else /* create initial targetInfo */
526 data1_node *node_tgtinfo;
535 data1_read_sgml (zei->dh, zei->nmem,
536 "<explain><targetInfo>TargetInfo\n"
538 "<namedResultSets>1</>\n"
539 "<multipleDBSearch>1</>\n"
540 "<nicknames><name>Zebra</></>\n"
542 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
544 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
545 nmem_destroy (zei->nmem);
548 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
550 assert (node_tgtinfo);
552 zebraExplain_initCommonInfo (zei, node_tgtinfo);
553 zebraExplain_initAccessInfo (zei, node_tgtinfo);
555 /* write now because we want to be sure about the sysno */
556 trec = rec_new (records);
557 trec->info[recInfo_fileType] =
558 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
559 trec->info[recInfo_databaseName] =
560 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
562 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
563 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
564 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
565 trec->size[recInfo_storeData] = sgml_len;
567 rec_put (records, &trec);
571 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
573 if (!zei->categoryList->dirty)
575 struct zebraCategoryListInfo *zcl = zei->categoryList;
579 zcl->data1_categoryList =
580 data1_read_sgml (zei->dh, zei->nmem,
581 "<explain><categoryList>CategoryList\n"
584 if (zcl->data1_categoryList)
586 assert (zcl->data1_categoryList->child);
587 node_cl = data1_search_tag (zei->dh,
588 zcl->data1_categoryList->child,
591 zebraExplain_initCommonInfo (zei, node_cl);
598 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
599 zebAttributeDetails zad)
602 struct zebSUInfoB **zsuip = &zad->SUInfo;
603 data1_node *node_adinfo, *node_zebra, *node_list, *np;
606 rec = rec_get (zei->records, zad->sysno);
608 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
610 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
612 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
614 node_list = data1_search_tag (zei->dh, node_zebra->child,
616 for (np = node_list->child; np; np = np->next)
618 data1_node *node_set = NULL;
619 data1_node *node_use = NULL;
620 data1_node *node_ordinal = NULL;
625 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
627 for (np2 = np->child; np2; np2 = np2->next)
629 if (np2->which != DATA1N_tag || !np2->child ||
630 np2->child->which != DATA1N_data)
632 if (!strcmp (np2->u.tag.tag, "set"))
633 node_set = np2->child;
634 else if (!strcmp (np2->u.tag.tag, "use"))
635 node_use = np2->child;
636 else if (!strcmp (np2->u.tag.tag, "ordinal"))
637 node_ordinal = np2->child;
639 assert (node_set && node_use && node_ordinal);
641 oid_str_len = node_set->u.data.len;
642 if (oid_str_len >= (int) sizeof(oid_str))
643 oid_str_len = sizeof(oid_str)-1;
644 memcpy (oid_str, node_set->u.data.data, oid_str_len);
645 oid_str[oid_str_len] = '\0';
647 *zsuip = (struct zebSUInfoB *)
648 nmem_malloc (zei->nmem, sizeof(**zsuip));
649 (*zsuip)->info.set = oid_getvalbyname (oid_str);
651 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
652 node_use->u.data.len);
653 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
654 node_ordinal->u.data.len);
655 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
656 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
657 zsuip = &(*zsuip)->next;
664 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
665 struct zebDatabaseInfoB *zdi)
668 data1_node *node_dbinfo, *node_zebra, *np;
671 rec = rec_get (zei->records, zdi->sysno);
673 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
675 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
677 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
679 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
682 && (np = data1_search_tag (zei->dh, node_zebra->child,
684 && np->child && np->child->which == DATA1N_data)
685 zdi->recordBytes = atoi_n (np->child->u.data.data,
686 np->child->u.data.len);
687 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
689 (np = data1_search_tag (zei->dh, np->child,
690 "recordCountActual")) &&
691 np->child->which == DATA1N_data)
693 zdi->recordCount = atoi_n (np->child->u.data.data,
694 np->child->u.data.len);
700 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
702 struct zebDatabaseInfoB *zdi;
705 if (zei->curDatabaseInfo &&
706 !strcmp (zei->curDatabaseInfo->databaseName, database))
708 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
710 if (!strcmp (zdi->databaseName, database))
716 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
721 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
723 zebraExplain_readDatabase (zei, zdi);
725 if (zdi->attributeDetails->readFlag)
728 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
730 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
732 zei->curDatabaseInfo = zdi;
736 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
738 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
740 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
741 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
742 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
745 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
747 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
749 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
752 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
754 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
755 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
756 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
759 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
760 zebAccessInfo accessInfo)
762 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
768 if ((p = accessInfo->attributeSetIds))
770 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
771 for (; p; p = p->next)
772 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
774 if ((p = accessInfo->schemas))
776 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
777 for (; p; p = p->next)
778 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
782 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
783 int explain_database)
785 struct zebDatabaseInfoB *zdi;
786 data1_node *node_dbinfo, *node_adinfo;
789 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
792 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
794 if (!strcmp (zdi->databaseName, database))
799 /* it's new really. make it */
800 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
801 zdi->next = zei->databaseInfo;
802 zei->databaseInfo = zdi;
804 zdi->recordCount = 0;
805 zdi->recordBytes = 0;
807 zdi->databaseName = nmem_strdup (zei->nmem, database);
809 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
814 zdi->data1_database =
815 data1_read_sgml (zei->dh, zei->nmem,
816 "<explain><databaseInfo>DatabaseInfo\n"
818 if (!zdi->data1_database)
821 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
823 assert (node_dbinfo);
825 zebraExplain_initCommonInfo (zei, node_dbinfo);
826 zebraExplain_initAccessInfo (zei, node_dbinfo);
828 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
829 database, zei->nmem);
831 if (explain_database)
832 data1_add_tagdata_text (zei->dh, node_dbinfo, "explainDatabase",
835 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
838 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
842 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
846 zei->curDatabaseInfo = zdi;
848 zdi->attributeDetails = (zebAttributeDetails)
849 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
850 zdi->attributeDetails->readFlag = 0;
851 zdi->attributeDetails->sysno = 0;
852 zdi->attributeDetails->dirty = 1;
853 zdi->attributeDetails->SUInfo = NULL;
854 zdi->attributeDetails->data1_tree =
855 data1_read_sgml (zei->dh, zei->nmem,
856 "<explain><attributeDetails>AttributeDetails\n"
860 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
862 assert (node_adinfo);
864 zebraExplain_initCommonInfo (zei, node_adinfo);
869 static void writeAttributeValueDetails (ZebraExplainInfo zei,
870 zebAttributeDetails zad,
871 data1_node *node_atvs, data1_attset *attset)
874 struct zebSUInfoB *zsui;
875 int set_ordinal = attset->reference;
876 data1_attset_child *c;
878 for (c = attset->children; c; c = c->next)
879 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
880 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
882 data1_node *node_attvalue, *node_value;
883 if (set_ordinal != zsui->info.set)
885 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
887 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
889 data1_add_tagdata_int (zei->dh, node_value, "numeric",
890 zsui->info.use, zei->nmem);
894 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
895 struct zebraCategoryListInfo *zcl,
902 data1_node *node_ci, *node_categoryList;
904 static char *category[] = {
916 node_categoryList = zcl->data1_categoryList;
919 logf (LOG_LOG, "zebraExplain_writeCategoryList");
922 drec = createRecord (zei->records, &sysno);
924 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
927 node_ci = data1_add_tag (zei->dh, node_ci, "categories", zei->nmem);
930 for (i = 0; category[i]; i++)
932 data1_node *node_cat = data1_add_tag (zei->dh, node_ci,
933 "category", zei->nmem);
935 data1_add_tagdata_text (zei->dh, node_cat, "name",
936 category[i], zei->nmem);
938 /* extract *searchable* keys from it. We do this here, because
939 record count, etc. is affected */
941 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
943 /* convert to "SGML" and write it */
945 data1_pr_tree (zei->dh, node_categoryList, stderr);
947 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
948 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
949 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
950 drec->size[recInfo_storeData] = sgml_len;
952 rec_put (zei->records, &drec);
955 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
956 zebAttributeDetails zad,
957 const char *databaseName,
963 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
964 struct zebSUInfoB *zsui;
972 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
975 drec = createRecord (zei->records, &zad->sysno);
976 assert (zad->data1_tree);
977 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
979 zebraExplain_updateCommonInfo (zei, node_adinfo);
981 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
982 databaseName, zei->nmem);
984 /* extract *searchable* keys from it. We do this here, because
985 record count, etc. is affected */
987 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
989 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
990 "attributesBySet", zei->nmem);
994 data1_node *node_asd;
995 data1_attset *attset;
996 int set_ordinal = -1;
997 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
999 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1000 && zsui->info.set > set_min)
1001 set_ordinal = zsui->info.set;
1003 if (set_ordinal < 0)
1005 set_min = set_ordinal;
1006 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
1007 "attributeSetDetails", zei->nmem);
1009 attset = data1_attset_search_id (zei->dh, set_ordinal);
1012 zebraExplain_loadAttsets (zei->dh, zei->res);
1013 attset = data1_attset_search_id (zei->dh, set_ordinal);
1020 oe.proto = PROTO_Z3950;
1021 oe.oclass = CLASS_ATTSET;
1022 oe.value = (enum oid_value) set_ordinal;
1024 if (oid_ent_to_oid (&oe, oid))
1026 data1_node *node_abt, *node_atd, *node_atvs;
1027 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
1030 node_abt = data1_add_tag (zei->dh, node_asd,
1031 "attributesByType", zei->nmem);
1032 node_atd = data1_add_tag (zei->dh, node_abt,
1033 "attributeTypeDetails", zei->nmem);
1034 data1_add_tagdata_int (zei->dh, node_atd,
1035 "type", 1, zei->nmem);
1036 node_atvs = data1_add_tag (zei->dh, node_atd,
1037 "attributeValues", zei->nmem);
1038 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1042 /* zebra info (private) */
1043 node_zebra = data1_make_tag (zei->dh, node_adinfo,
1044 "zebraInfo", zei->nmem);
1045 node_list = data1_make_tag (zei->dh, node_zebra,
1046 "attrlist", zei->nmem);
1047 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1049 struct oident oident;
1051 data1_node *node_attr;
1053 node_attr = data1_add_tag (zei->dh, node_list, "attr", zei->nmem);
1055 oident.proto = PROTO_Z3950;
1056 oident.oclass = CLASS_ATTSET;
1057 oident.value = (enum oid_value) zsui->info.set;
1058 oid_ent_to_oid (&oident, oid);
1060 data1_add_tagdata_text (zei->dh, node_attr, "set",
1061 oident.desc, zei->nmem);
1062 data1_add_tagdata_int (zei->dh, node_attr, "use",
1063 zsui->info.use, zei->nmem);
1064 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
1065 zsui->info.ordinal, zei->nmem);
1067 /* convert to "SGML" and write it */
1069 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1071 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1073 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1074 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1075 drec->size[recInfo_storeData] = sgml_len;
1077 rec_put (zei->records, &drec);
1080 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1081 struct zebDatabaseInfoB *zdi,
1087 data1_node *node_dbinfo, *node_count, *node_zebra;
1094 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1096 drec = createRecord (zei->records, &zdi->sysno);
1097 assert (zdi->data1_database);
1098 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1101 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1102 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1104 /* extract *searchable* keys from it. We do this here, because
1105 record count, etc. is affected */
1107 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1109 node_count = data1_make_tag (zei->dh, node_dbinfo,
1110 "recordCount", zei->nmem);
1111 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
1112 zdi->recordCount, zei->nmem);
1114 /* zebra info (private) */
1115 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
1116 "zebraInfo", zei->nmem);
1117 data1_add_tagdata_int (zei->dh, node_zebra,
1118 "recordBytes", zdi->recordBytes, zei->nmem);
1119 /* convert to "SGML" and write it */
1121 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1123 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1125 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1126 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1127 drec->size[recInfo_storeData] = sgml_len;
1129 rec_put (zei->records, &drec);
1132 static void writeAttributeValues (ZebraExplainInfo zei,
1133 data1_node *node_values,
1134 data1_attset *attset)
1137 data1_attset_child *c;
1142 for (c = attset->children; c; c = c->next)
1143 writeAttributeValues (zei, node_values, c->child);
1144 for (atts = attset->atts; atts; atts = atts->next)
1146 data1_node *node_value;
1148 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1150 data1_add_tagdata_text (zei->dh, node_value, "name",
1151 atts->name, zei->nmem);
1152 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1153 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1154 atts->value, zei->nmem);
1159 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1166 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1167 data1_node *node_values;
1168 struct oident *entp;
1169 struct data1_attset *attset = NULL;
1171 if ((entp = oid_getentbyoid (o->oid)))
1172 attset = data1_attset_search_id (zei->dh, entp->value);
1175 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1176 attset ? attset->name : "<unknown>");
1179 drec = createRecord (zei->records, &o->sysno);
1181 data1_read_sgml (zei->dh, zei->nmem,
1182 "<explain><attributeSetInfo>AttributeSetInfo\n"
1185 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1186 "attributeSetInfo");
1188 zebraExplain_initCommonInfo (zei, node_attinfo);
1189 zebraExplain_updateCommonInfo (zei, node_attinfo);
1191 data1_add_tagdata_oid (zei->dh, node_attinfo,
1192 "oid", o->oid, zei->nmem);
1193 if (attset && attset->name)
1194 data1_add_tagdata_text (zei->dh, node_attinfo,
1195 "name", attset->name, zei->nmem);
1197 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1198 "attributes", zei->nmem);
1199 node_atttype = data1_make_tag (zei->dh, node_attributes,
1200 "attributeType", zei->nmem);
1201 data1_add_tagdata_text (zei->dh, node_atttype,
1202 "name", "Use", zei->nmem);
1203 data1_add_tagdata_text (zei->dh, node_atttype,
1204 "description", "Use Attribute", zei->nmem);
1205 data1_add_tagdata_int (zei->dh, node_atttype,
1206 "type", 1, zei->nmem);
1207 node_values = data1_add_tag (zei->dh, node_atttype,
1208 "attributeValues", zei->nmem);
1210 writeAttributeValues (zei, node_values, attset);
1212 /* extract *searchable* keys from it. We do this here, because
1213 record count, etc. is affected */
1215 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1216 /* convert to "SGML" and write it */
1218 data1_pr_tree (zei->dh, node_root, stderr);
1220 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1221 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1222 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1223 drec->size[recInfo_storeData] = sgml_len;
1225 rec_put (zei->records, &drec);
1228 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1230 struct zebDatabaseInfoB *zdi;
1231 data1_node *node_tgtinfo, *node_list, *node_zebra;
1240 trec = rec_get (zei->records, 1);
1241 xfree (trec->info[recInfo_storeData]);
1243 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1245 assert (node_tgtinfo);
1247 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1248 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1250 /* convert to "SGML" and write it */
1252 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1254 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1255 "zebraInfo", zei->nmem);
1256 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1257 ZEBRAVER, zei->nmem);
1258 node_list = data1_add_tag (zei->dh, node_zebra,
1259 "databaseList", zei->nmem);
1260 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1262 data1_node *node_db;
1263 node_db = data1_add_tag (zei->dh, node_list,
1264 "database", zei->nmem);
1265 data1_add_tagdata_text (zei->dh, node_db, "name",
1266 zdi->databaseName, zei->nmem);
1267 data1_add_tagdata_int (zei->dh, node_db, "id",
1268 zdi->sysno, zei->nmem);
1269 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1270 zdi->attributeDetails->sysno, zei->nmem);
1272 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1273 zei->ordinalSU, zei->nmem);
1275 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1276 zei->runNumber, zei->nmem);
1279 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1281 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1283 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1284 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1285 trec->size[recInfo_storeData] = sgml_len;
1287 rec_put (zei->records, &trec);
1290 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1292 struct zebSUInfoB *zsui;
1294 assert (zei->curDatabaseInfo);
1295 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1296 zsui; zsui=zsui->next)
1297 if (zsui->info.use == use && zsui->info.set == set)
1298 return zsui->info.ordinal;
1302 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1303 const char **db, int *set, int *use)
1305 struct zebDatabaseInfoB *zdb;
1306 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1308 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1309 for ( ;zsui; zsui = zsui->next)
1310 if (zsui->info.ordinal == ord)
1312 *db = zdb->databaseName;
1313 *set = zsui->info.set;
1314 *use = zsui->info.use;
1321 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1322 zebAccessObject *op,
1327 for (ao = *op; ao; ao = ao->next)
1328 if (!oid_oidcmp (oid, ao->oid))
1332 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1335 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1342 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1347 oe.proto = PROTO_Z3950;
1348 oe.oclass = CLASS_ATTSET;
1349 oe.value = (enum oid_value) set;
1351 if (oid_ent_to_oid (&oe, oid))
1353 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1354 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1355 accessInfo->attributeSetIds, oid);
1359 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1361 struct zebSUInfoB *zsui;
1363 assert (zei->curDatabaseInfo);
1364 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1365 zsui; zsui=zsui->next)
1366 if (zsui->info.use == use && zsui->info.set == set)
1368 zebraExplain_addAttributeSet (zei, set);
1369 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1370 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1371 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1372 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1374 zsui->info.set = set;
1375 zsui->info.use = use;
1376 zsui->info.ordinal = (zei->ordinalSU)++;
1377 return zsui->info.ordinal;
1380 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1382 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1383 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1384 accessInfo->schemas, oid);
1387 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1389 assert (zei->curDatabaseInfo);
1393 zei->curDatabaseInfo->recordBytes += adjust_num;
1394 zei->curDatabaseInfo->dirty = 1;
1398 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1400 assert (zei->curDatabaseInfo);
1404 zei->curDatabaseInfo->recordCount += adjust_num;
1405 zei->curDatabaseInfo->dirty = 1;
1409 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1413 return zei->runNumber += adjust_num;
1416 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1418 RecordAttr *recordAttr;
1420 if (rec->info[recInfo_attr])
1421 return (RecordAttr *) rec->info[recInfo_attr];
1422 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1423 rec->info[recInfo_attr] = (char *) recordAttr;
1424 rec->size[recInfo_attr] = sizeof(*recordAttr);
1426 recordAttr->recordSize = 0;
1427 recordAttr->recordOffset = 0;
1428 recordAttr->runNumber = zei->runNumber;
1432 static void att_loadset(void *p, const char *n, const char *name)
1434 data1_handle dh = (data1_handle) p;
1435 if (!data1_get_attset (dh, name))
1436 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1439 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1441 res_trav(res, "attset", dh, att_loadset);
1445 zebraExplain_addSU adds to AttributeDetails for a database and
1446 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1447 exist for the database.
1449 If the database doesn't exist globally (in TargetInfo) an
1450 AttributeSetInfo must be added (globally).