1 /* $Id: zinfo.c,v 1.57 2006-03-30 09:52:15 adam Exp $
2 Copyright (C) 1995-2005
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include <sys/types.h>
29 #include <idzebra/version.h>
36 #define ZEB_SU_SET_USE 1
50 struct zebSUInfo info;
51 struct zebSUInfoB *next;
54 typedef struct zebAccessObjectB *zebAccessObject;
55 struct zebAccessObjectB {
62 typedef struct zebAccessInfoB *zebAccessInfo;
63 struct zebAccessInfoB {
64 zebAccessObject attributeSetIds;
65 zebAccessObject schemas;
69 struct zebSUInfoB *SUInfo;
73 data1_node *data1_tree;
74 } *zebAttributeDetails;
76 struct zebDatabaseInfoB {
77 zebAttributeDetails attributeDetails;
80 data1_node *data1_database;
81 zint recordCount; /* records in db */
82 zint recordBytes; /* size of records */
83 SYSNO sysno; /* sysno of database info */
84 int readFlag; /* 1: read is needed when referenced; 0 if not */
85 int dirty; /* 1: database is dirty: write is needed */
86 struct zebDatabaseInfoB *next;
87 zebAccessInfo accessInfo;
90 struct zebraExplainAttset {
93 struct zebraExplainAttset *next;
96 struct zebraCategoryListInfo {
99 data1_node *data1_categoryList;
102 struct zebraExplainInfo {
111 struct zebraExplainAttset *attsets;
113 data1_node *data1_target;
114 struct zebraCategoryListInfo *categoryList;
115 struct zebDatabaseInfoB *databaseInfo;
116 struct zebDatabaseInfoB *curDatabaseInfo;
117 zebAccessInfo accessInfo;
118 char date[15]; /* YYYY MMDD HH MM SS */
119 int (*updateFunc)(void *handle, Record drec, data1_node *n);
123 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
124 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
126 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
128 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
131 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
132 struct zebDatabaseInfoB *zdi,
134 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
135 zebAttributeDetails zad,
136 const char *databaseName,
138 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
139 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
142 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
143 struct zebraCategoryListInfo *zcl,
147 static Record createRecord(Records records, SYSNO *sysno)
152 rec = rec_get(records, *sysno);
155 xfree(rec->info[recInfo_storeData]);
159 rec = rec_new(records);
164 rec->info[recInfo_fileType] =
165 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
166 rec->info[recInfo_databaseName] =
167 rec_strdup("IR-Explain-1",
168 &rec->size[recInfo_databaseName]);
173 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
177 zei->updateHandle = handle;
180 struct zebDatabaseInfoB *zdi;
183 /* write each database info record */
184 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
186 zebraExplain_writeDatabase(zei, zdi, 1);
187 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
188 zdi->databaseName, 1);
190 zebraExplain_writeTarget(zei, 1);
191 zebraExplain_writeCategoryList(zei,
194 assert(zei->accessInfo);
195 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
197 zebraExplain_writeAttributeSet(zei, o, 1);
198 for (o = zei->accessInfo->schemas; o; o = o->next)
201 /* zebraExplain_writeSchema(zei, o, 1); */
204 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
206 zebraExplain_writeDatabase(zei, zdi, 0);
207 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
208 zdi->databaseName, 0);
210 zebraExplain_writeTarget(zei, 0);
214 void zebraExplain_close(ZebraExplainInfo zei)
217 yaz_log(YLOG_LOG, "zebraExplain_close");
221 zebraExplain_flush(zei, zei->updateHandle);
222 nmem_destroy(zei->nmem);
225 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
230 for (np = n->child; np; np = np->next)
237 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
239 len = np->child->u.data.len;
242 memcpy(str, np->child->u.data.data, len);
245 oid = odr_getoidbystr_nmem(zei->nmem, str);
247 for (ao = *op; ao; ao = ao->next)
248 if (!oid_oidcmp(oid, ao->oid))
255 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
265 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
266 zebAccessInfo *accessInfo)
272 *accessInfo = (zebAccessInfo)
273 nmem_malloc(zei->nmem, sizeof(**accessInfo));
274 (*accessInfo)->attributeSetIds = NULL;
275 (*accessInfo)->schemas = NULL;
279 if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
281 if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
282 zebraExplain_mergeOids(zei, np,
283 &(*accessInfo)->attributeSetIds);
284 if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
285 zebraExplain_mergeOids(zei, np,
286 &(*accessInfo)->schemas);
295 databaseList (list of databases)
300 targetInfo: TargetInfo
307 dateAdded: 20030630190601
308 dateChanged: 20030630190601
314 oid: 1.2.840.10003.3.2
315 oid: 1.2.840.10003.3.5
316 oid: 1.2.840.10003.3.1
318 oid: 1.2.840.10003.13.1000.81.2
319 oid: 1.2.840.10003.13.2
326 attributeDetailsId: 51
330 attributeDetailsId: 53
333 nextResultSetPosition = 2
336 ZebraExplainInfo zebraExplain_open(
337 Records records, data1_handle dh,
341 int (*updateFunc)(void *handle, Record drec, data1_node *n))
344 ZebraExplainInfo zei;
345 struct zebDatabaseInfoB **zdip;
348 NMEM nmem = nmem_create();
351 yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
353 zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
354 zei->databaseInfo = 0;
355 zei->write_flag = writeFlag;
356 zei->updateHandle = updateHandle;
357 zei->updateFunc = updateFunc;
359 zei->ordinalDatabase = 1;
360 zei->curDatabaseInfo = NULL;
361 zei->records = records;
366 zei->categoryList = (struct zebraCategoryListInfo *)
367 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
368 zei->categoryList->sysno = 0;
369 zei->categoryList->dirty = 0;
370 zei->categoryList->data1_categoryList = NULL;
372 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
375 tm = localtime(&our_time);
376 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
377 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
378 tm->tm_hour, tm->tm_min, tm->tm_sec);
380 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
383 zdip = &zei->databaseInfo;
384 trec = rec_get_root(records); /* get "root" record */
389 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
390 if (trec) /* targetInfo already exists ... */
392 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
394 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
396 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
398 if (!zei->data1_target)
401 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
402 nmem_destroy(zei->nmem);
406 data1_pr_tree(zei->dh, zei->data1_target, stderr);
408 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
410 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
413 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
418 node_list = data1_search_tag(zei->dh, node_zebra->child,
421 np = node_list->child;
423 for(; np; np = np->next)
425 data1_node *node_name = NULL;
426 data1_node *node_id = NULL;
427 data1_node *node_aid = NULL;
429 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
431 for(np2 = np->child; np2; np2 = np2->next)
433 if (np2->which != DATA1N_tag)
435 if (!strcmp(np2->u.tag.tag, "name"))
436 node_name = np2->child;
437 else if (!strcmp(np2->u.tag.tag, "id"))
438 node_id = np2->child;
439 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
440 node_aid = np2->child;
442 assert(node_id && node_name && node_aid);
444 *zdip =(struct zebDatabaseInfoB *)
445 nmem_malloc(zei->nmem, sizeof(**zdip));
446 (*zdip)->readFlag = 1;
448 (*zdip)->data1_database = NULL;
449 (*zdip)->recordCount = 0;
450 (*zdip)->recordBytes = 0;
451 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
453 (*zdip)->databaseName = (char *)
454 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
455 memcpy((*zdip)->databaseName, node_name->u.data.data,
456 node_name->u.data.len);
457 (*zdip)->databaseName[node_name->u.data.len] = '\0';
458 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
459 node_id->u.data.len);
460 (*zdip)->attributeDetails = (zebAttributeDetails)
461 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
462 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
463 node_aid->u.data.len);
464 (*zdip)->attributeDetails->readFlag = 1;
465 (*zdip)->attributeDetails->dirty = 0;
466 (*zdip)->attributeDetails->SUInfo = NULL;
468 zdip = &(*zdip)->next;
472 np = data1_search_tag(zei->dh, node_zebra->child,
475 assert (np && np->which == DATA1N_data);
476 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
478 np = data1_search_tag(zei->dh, node_zebra->child,
481 assert (np && np->which == DATA1N_data);
482 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
484 np = data1_search_tag(zei->dh, node_zebra->child,
487 assert (np && np->which == DATA1N_data);
488 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
489 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
494 else /* create initial targetInfo */
496 data1_node *node_tgtinfo;
505 data1_read_sgml(zei->dh, zei->nmem,
506 "<explain><targetInfo>TargetInfo\n"
508 "<namedResultSets>1</>\n"
509 "<multipleDBSearch>1</>\n"
510 "<nicknames><name>Zebra</></>\n"
512 if (!zei->data1_target)
514 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
515 nmem_destroy(zei->nmem);
518 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
520 assert(node_tgtinfo);
522 zebraExplain_initCommonInfo(zei, node_tgtinfo);
523 zebraExplain_initAccessInfo(zei, node_tgtinfo);
525 /* write now because we want to be sure about the sysno */
526 trec = rec_new(records);
529 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
530 nmem_destroy(zei->nmem);
533 trec->info[recInfo_fileType] =
534 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
535 trec->info[recInfo_databaseName] =
536 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
538 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
539 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
540 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
541 trec->size[recInfo_storeData] = sgml_len;
543 rec_put(records, &trec);
547 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
549 if (!zei->categoryList->dirty)
551 struct zebraCategoryListInfo *zcl = zei->categoryList;
555 zcl->data1_categoryList =
556 data1_read_sgml(zei->dh, zei->nmem,
557 "<explain><categoryList>CategoryList\n"
560 if (zcl->data1_categoryList)
562 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
565 zebraExplain_initCommonInfo(zei, node_cl);
572 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
573 zebAttributeDetails zad)
576 struct zebSUInfoB **zsuip = &zad->SUInfo;
577 data1_node *node_adinfo, *node_zebra, *node_list, *np;
580 rec = rec_get(zei->records, zad->sysno);
582 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
584 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
585 "/attributeDetails");
586 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
588 node_list = data1_search_tag(zei->dh, node_zebra->child,
590 for (np = node_list->child; np; np = np->next)
592 data1_node *node_set = NULL;
593 data1_node *node_use = NULL;
594 data1_node *node_str = NULL;
595 data1_node *node_ordinal = NULL;
596 data1_node *node_type = NULL;
601 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
603 for (np2 = np->child; np2; np2 = np2->next)
605 if (np2->which != DATA1N_tag || !np2->child ||
606 np2->child->which != DATA1N_data)
608 if (!strcmp(np2->u.tag.tag, "set"))
609 node_set = np2->child;
610 else if (!strcmp(np2->u.tag.tag, "use"))
611 node_use = np2->child;
612 else if (!strcmp(np2->u.tag.tag, "str"))
613 node_str = np2->child;
614 else if (!strcmp(np2->u.tag.tag, "ordinal"))
615 node_ordinal = np2->child;
616 else if (!strcmp(np2->u.tag.tag, "type"))
617 node_type = np2->child;
619 assert(node_ordinal);
621 *zsuip = (struct zebSUInfoB *)
622 nmem_malloc(zei->nmem, sizeof(**zsuip));
624 if (node_type && node_type->u.data.len > 0)
625 (*zsuip)->info.index_type = node_type->u.data.data[0];
628 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
629 (*zsuip)->info.index_type = 'w';
632 if (node_set && node_use)
634 (*zsuip)->info.which = ZEB_SU_SET_USE;
636 oid_str_len = node_set->u.data.len;
637 if (oid_str_len >= (int) sizeof(oid_str))
638 oid_str_len = sizeof(oid_str)-1;
639 memcpy(oid_str, node_set->u.data.data, oid_str_len);
640 oid_str[oid_str_len] = '\0';
642 (*zsuip)->info.u.su.set = oid_getvalbyname(oid_str);
644 (*zsuip)->info.u.su.use = atoi_n(node_use->u.data.data,
645 node_use->u.data.len);
646 yaz_log(YLOG_DEBUG, "set=%d use=%d ordinal=%d",
647 (*zsuip)->info.u.su.set, (*zsuip)->info.u.su.use,
648 (*zsuip)->info.ordinal);
652 (*zsuip)->info.which = ZEB_SU_STR;
654 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
655 node_str->u.data.data,
656 node_str->u.data.len);
660 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
663 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
664 node_ordinal->u.data.len);
665 zsuip = &(*zsuip)->next;
672 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
673 struct zebDatabaseInfoB *zdi)
676 data1_node *node_dbinfo, *node_zebra, *np;
679 rec = rec_get (zei->records, zdi->sysno);
681 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
683 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
685 assert (node_dbinfo);
686 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
688 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
691 && (np = data1_search_tag (zei->dh, node_zebra->child,
693 && np->child && np->child->which == DATA1N_data)
694 zdi->recordBytes = atoi_zn (np->child->u.data.data,
695 np->child->u.data.len);
698 && (np = data1_search_tag (zei->dh, node_zebra->child,
700 && np->child && np->child->which == DATA1N_data)
701 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
702 np->child->u.data.len);
704 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
706 (np = data1_search_tag (zei->dh, np->child,
707 "recordCountActual")) &&
708 np->child->which == DATA1N_data)
710 zdi->recordCount = atoi_zn (np->child->u.data.data,
711 np->child->u.data.len);
717 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
719 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
723 if (*zdip == zei->curDatabaseInfo)
725 struct zebDatabaseInfoB *zdi = *zdip;
729 zei->updateHandle = update_handle;
731 if (zdi->attributeDetails)
733 /* remove attribute details keys and delete it */
734 zebAttributeDetails zad = zdi->attributeDetails;
736 rec = rec_get(zei->records, zad->sysno);
737 (*zei->updateFunc)(zei->updateHandle, rec, 0);
740 /* remove database record keys and delete it */
741 rec = rec_get (zei->records, zdi->sysno);
742 (*zei->updateFunc)(zei->updateHandle, rec, 0);
745 /* remove from list */
748 /* current database is IR-Explain-1 */
751 zdip = &(*zdip)->next;
756 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
758 struct zebDatabaseInfoB *zdi;
759 const char *database_n = strrchr (database, '/');
764 database_n = database;
767 if (zei->curDatabaseInfo &&
768 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
770 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
772 if (!STRCASECMP (zdi->databaseName, database_n))
778 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
783 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
785 zebraExplain_readDatabase (zei, zdi);
787 if (zdi->attributeDetails->readFlag)
790 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
792 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
794 zei->curDatabaseInfo = zdi;
798 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
800 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
801 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
802 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
803 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
806 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
808 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
810 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
814 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
816 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
817 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
818 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
821 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
822 zebAccessInfo accessInfo)
824 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
830 data1_pr_tree (zei->dh, n, stdout);
835 if ((p = accessInfo->attributeSetIds))
837 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
838 for (; p; p = p->next)
839 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
841 if ((p = accessInfo->schemas))
843 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
844 for (; p; p = p->next)
845 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
849 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
850 int explain_database)
852 struct zebDatabaseInfoB *zdi;
853 data1_node *node_dbinfo, *node_adinfo;
854 const char *database_n = strrchr (database, '/');
859 database_n = database;
862 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
865 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
867 if (!STRCASECMP (zdi->databaseName, database_n))
872 /* it's new really. make it */
873 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
874 zdi->next = zei->databaseInfo;
875 zei->databaseInfo = zdi;
877 zdi->recordCount = 0;
878 zdi->recordBytes = 0;
880 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
882 zdi->ordinalDatabase = zei->ordinalDatabase++;
884 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
889 zdi->data1_database =
890 data1_read_sgml (zei->dh, zei->nmem,
891 "<explain><databaseInfo>DatabaseInfo\n"
893 if (!zdi->data1_database)
896 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
898 assert (node_dbinfo);
900 zebraExplain_initCommonInfo (zei, node_dbinfo);
901 zebraExplain_initAccessInfo (zei, node_dbinfo);
903 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
904 database, zei->nmem);
906 if (explain_database)
907 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
910 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
913 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
917 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
921 zei->curDatabaseInfo = zdi;
923 zdi->attributeDetails = (zebAttributeDetails)
924 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
925 zdi->attributeDetails->readFlag = 0;
926 zdi->attributeDetails->sysno = 0;
927 zdi->attributeDetails->dirty = 1;
928 zdi->attributeDetails->SUInfo = NULL;
929 zdi->attributeDetails->data1_tree =
930 data1_read_sgml (zei->dh, zei->nmem,
931 "<explain><attributeDetails>AttributeDetails\n"
934 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
935 "/attributeDetails");
936 assert (node_adinfo);
938 zebraExplain_initCommonInfo (zei, node_adinfo);
943 static void writeAttributeValueDetails (ZebraExplainInfo zei,
944 zebAttributeDetails zad,
945 data1_node *node_atvs, data1_attset *attset)
948 struct zebSUInfoB *zsui;
949 int set_ordinal = attset->reference;
950 data1_attset_child *c;
952 for (c = attset->children; c; c = c->next)
953 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
954 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
956 if (zsui->info.which == ZEB_SU_SET_USE &&
957 set_ordinal == zsui->info.u.su.set)
959 data1_node *node_attvalue, *node_value;
960 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
961 0 /* attr */, node_atvs);
962 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
963 0 /* attr */, node_attvalue);
964 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
965 zsui->info.u.su.use, zei->nmem);
970 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
971 struct zebraCategoryListInfo *zcl,
978 data1_node *node_ci, *node_categoryList;
980 static char *category[] = {
992 node_categoryList = zcl->data1_categoryList;
995 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
998 drec = createRecord (zei->records, &sysno);
1002 node_ci = data1_search_tag (zei->dh, node_categoryList,
1005 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
1009 for (i = 0; category[i]; i++)
1011 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
1012 0 /* attr */, node_ci);
1014 data1_mk_tag_data_text (zei->dh, node_cat, "name",
1015 category[i], zei->nmem);
1017 /* extract *searchable* keys from it. We do this here, because
1018 record count, etc. is affected */
1020 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1022 /* convert to "SGML" and write it */
1024 data1_pr_tree (zei->dh, node_categoryList, stderr);
1026 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1027 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1028 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1029 drec->size[recInfo_storeData] = sgml_len;
1031 rec_put (zei->records, &drec);
1034 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1035 zebAttributeDetails zad,
1036 const char *databaseName,
1042 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
1043 struct zebSUInfoB *zsui;
1051 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1054 drec = createRecord (zei->records, &zad->sysno);
1057 assert (zad->data1_tree);
1059 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1060 "/attributeDetails");
1061 zebraExplain_updateCommonInfo (zei, node_adinfo);
1063 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1064 databaseName, zei->nmem);
1066 /* extract *searchable* keys from it. We do this here, because
1067 record count, etc. is affected */
1069 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1071 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
1072 "attributesBySet", node_adinfo);
1076 data1_node *node_asd;
1077 data1_attset *attset;
1078 int set_ordinal = -1;
1079 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1081 if (zsui->info.which == ZEB_SU_SET_USE &&
1082 (set_ordinal < 0 || set_ordinal > zsui->info.u.su.set)
1083 && zsui->info.u.su.set > set_min)
1084 set_ordinal = zsui->info.u.su.set;
1086 if (set_ordinal < 0)
1088 set_min = set_ordinal;
1089 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1090 "attributeSetDetails",
1091 0 /* attr */, node_attributesBySet);
1093 attset = data1_attset_search_id (zei->dh, set_ordinal);
1096 zebraExplain_loadAttsets (zei->dh, zei->res);
1097 attset = data1_attset_search_id (zei->dh, set_ordinal);
1104 oe.proto = PROTO_Z3950;
1105 oe.oclass = CLASS_ATTSET;
1106 oe.value = (enum oid_value) set_ordinal;
1108 if (oid_ent_to_oid (&oe, oid))
1110 data1_node *node_abt, *node_atd, *node_atvs;
1111 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1114 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1116 0 /*attr */, node_asd);
1117 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1118 "attributeTypeDetails",
1119 0 /* attr */, node_abt);
1120 data1_mk_tag_data_int (zei->dh, node_atd,
1121 "type", 1, zei->nmem);
1122 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1124 0 /* attr */, node_atd);
1125 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1129 /* zebra info (private) */
1130 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1131 "zebraInfo", node_adinfo);
1132 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1133 "attrlist", node_zebra);
1134 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1136 struct oident oident;
1138 data1_node *node_attr;
1139 char index_type_str[2];
1142 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1145 index_type_str[0] = zsui->info.index_type;
1146 index_type_str[1] = '\0';
1147 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1148 index_type_str, zei->nmem);
1149 if (zsui->info.which == ZEB_SU_SET_USE)
1151 oident.proto = PROTO_Z3950;
1152 oident.oclass = CLASS_ATTSET;
1153 oident.value = (enum oid_value) zsui->info.u.su.set;
1154 oid_ent_to_oid (&oident, oid);
1156 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1157 oident.desc, zei->nmem);
1158 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1159 zsui->info.u.su.use, zei->nmem);
1161 else if (zsui->info.which == ZEB_SU_STR)
1163 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1164 zsui->info.u.str, zei->nmem);
1166 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1167 zsui->info.ordinal, zei->nmem);
1169 /* convert to "SGML" and write it */
1171 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1173 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1175 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1176 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1177 drec->size[recInfo_storeData] = sgml_len;
1179 rec_put (zei->records, &drec);
1182 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1183 struct zebDatabaseInfoB *zdi,
1189 data1_node *node_dbinfo, *node_count, *node_zebra;
1196 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1198 drec = createRecord (zei->records, &zdi->sysno);
1201 assert (zdi->data1_database);
1203 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1206 assert (node_dbinfo);
1207 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1208 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1210 /* extract *searchable* keys from it. We do this here, because
1211 record count, etc. is affected */
1213 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1215 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1216 "recordCount", node_dbinfo);
1217 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1218 zdi->recordCount, zei->nmem);
1220 /* zebra info (private) */
1221 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1222 "zebraInfo", node_dbinfo);
1223 data1_mk_tag_data_zint (zei->dh, node_zebra,
1224 "recordBytes", zdi->recordBytes, zei->nmem);
1226 data1_mk_tag_data_zint(zei->dh, node_zebra,
1227 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1229 /* convert to "SGML" and write it */
1231 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1233 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
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 writeAttributeValues (ZebraExplainInfo zei,
1243 data1_node *node_values,
1244 data1_attset *attset)
1247 data1_attset_child *c;
1252 for (c = attset->children; c; c = c->next)
1253 writeAttributeValues (zei, node_values, c->child);
1254 for (atts = attset->atts; atts; atts = atts->next)
1256 data1_node *node_value;
1258 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1259 0 /* attr */, node_values);
1260 data1_mk_tag_data_text (zei->dh, node_value, "name",
1261 atts->name, zei->nmem);
1262 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1263 0 /* attr */, node_value);
1264 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1265 atts->value, zei->nmem);
1270 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1277 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1278 data1_node *node_values;
1279 struct oident *entp;
1280 struct data1_attset *attset = NULL;
1282 if ((entp = oid_getentbyoid (o->oid)))
1283 attset = data1_attset_search_id (zei->dh, entp->value);
1286 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1287 attset ? attset->name : "<unknown>");
1290 drec = createRecord (zei->records, &o->sysno);
1294 data1_read_sgml (zei->dh, zei->nmem,
1295 "<explain><attributeSetInfo>AttributeSetInfo\n"
1298 node_attinfo = data1_search_tag (zei->dh, node_root,
1299 "/attributeSetInfo");
1301 assert (node_attinfo);
1302 zebraExplain_initCommonInfo (zei, node_attinfo);
1303 zebraExplain_updateCommonInfo (zei, node_attinfo);
1305 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1306 "oid", o->oid, zei->nmem);
1307 if (attset && attset->name)
1308 data1_mk_tag_data_text (zei->dh, node_attinfo,
1309 "name", attset->name, zei->nmem);
1311 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1312 "attributes", node_attinfo);
1313 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1314 "attributeType", node_attributes);
1315 data1_mk_tag_data_text (zei->dh, node_atttype,
1316 "name", "Use", zei->nmem);
1317 data1_mk_tag_data_text (zei->dh, node_atttype,
1318 "description", "Use Attribute", zei->nmem);
1319 data1_mk_tag_data_int (zei->dh, node_atttype,
1320 "type", 1, zei->nmem);
1321 node_values = data1_mk_tag (zei->dh, zei->nmem,
1322 "attributeValues", 0 /* attr */, node_atttype);
1324 writeAttributeValues (zei, node_values, attset);
1326 /* extract *searchable* keys from it. We do this here, because
1327 record count, etc. is affected */
1329 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1330 /* convert to "SGML" and write it */
1332 data1_pr_tree (zei->dh, node_root, stderr);
1334 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1335 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1336 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1337 drec->size[recInfo_storeData] = sgml_len;
1339 rec_put (zei->records, &drec);
1342 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1344 struct zebDatabaseInfoB *zdi;
1345 data1_node *node_tgtinfo, *node_list, *node_zebra;
1354 trec = rec_get_root(zei->records);
1355 xfree (trec->info[recInfo_storeData]);
1357 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1359 assert (node_tgtinfo);
1361 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1362 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1364 /* convert to "SGML" and write it */
1366 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1368 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1369 "zebraInfo", node_tgtinfo);
1370 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1371 ZEBRAVER, zei->nmem);
1372 node_list = data1_mk_tag (zei->dh, zei->nmem,
1373 "databaseList", 0 /* attr */, node_zebra);
1374 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1376 data1_node *node_db;
1377 node_db = data1_mk_tag (zei->dh, zei->nmem,
1378 "database", 0 /* attr */, node_list);
1379 data1_mk_tag_data_text (zei->dh, node_db, "name",
1380 zdi->databaseName, zei->nmem);
1381 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1382 zdi->sysno, zei->nmem);
1383 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1384 zdi->attributeDetails->sysno, zei->nmem);
1386 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1387 zei->ordinalSU, zei->nmem);
1389 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
1390 zei->ordinalDatabase, zei->nmem);
1392 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1393 zei->runNumber, zei->nmem);
1396 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1398 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1400 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1401 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1402 trec->size[recInfo_storeData] = sgml_len;
1404 rec_put (zei->records, &trec);
1407 int zebraExplain_lookup_attr_su_any_index(ZebraExplainInfo zei,
1410 struct zebSUInfoB *zsui;
1412 assert (zei->curDatabaseInfo);
1413 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1414 zsui; zsui=zsui->next)
1415 if (zsui->info.which == ZEB_SU_SET_USE &&
1416 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1417 return zsui->info.ordinal;
1421 int zebraExplain_lookup_attr_su(ZebraExplainInfo zei, int index_type,
1424 struct zebSUInfoB *zsui;
1426 assert (zei->curDatabaseInfo);
1427 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1428 zsui; zsui=zsui->next)
1429 if (zsui->info.index_type == index_type &&
1430 zsui->info.which == ZEB_SU_SET_USE &&
1431 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1432 return zsui->info.ordinal;
1436 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
1439 struct zebSUInfoB *zsui;
1441 assert (zei->curDatabaseInfo);
1442 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1443 zsui; zsui=zsui->next)
1444 if (zsui->info.index_type == index_type &&
1445 zsui->info.which == ZEB_SU_STR && !strcmp(zsui->info.u.str, str))
1446 return zsui->info.ordinal;
1450 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1451 int (*f)(void *handle, int ord))
1453 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1456 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1457 for ( ;zsui; zsui = zsui->next)
1458 (*f)(handle, zsui->info.ordinal);
1463 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1467 const char **string_index)
1469 struct zebDatabaseInfoB *zdb;
1480 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1482 struct zebSUInfoB *zsui;
1484 if (zdb->attributeDetails->readFlag)
1485 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1487 for (zsui = zdb->attributeDetails->SUInfo; zsui; zsui = zsui->next)
1488 if (zsui->info.ordinal == ord)
1491 *db = zdb->databaseName;
1492 if (zsui->info.which == ZEB_SU_SET_USE)
1495 *set = zsui->info.u.su.set;
1497 *use = zsui->info.u.su.use;
1500 if (zsui->info.which == ZEB_SU_STR)
1502 *string_index = zsui->info.u.str;
1505 *index_type = zsui->info.index_type;
1512 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1513 zebAccessObject *op,
1518 for (ao = *op; ao; ao = ao->next)
1519 if (!oid_oidcmp (oid, ao->oid))
1523 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1526 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1533 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1538 oe.proto = PROTO_Z3950;
1539 oe.oclass = CLASS_ATTSET;
1540 oe.value = (enum oid_value) set;
1542 if (oid_ent_to_oid (&oe, oid))
1544 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1545 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1546 accessInfo->attributeSetIds, oid);
1550 int zebraExplain_add_attr_su(ZebraExplainInfo zei, int index_type,
1553 struct zebSUInfoB *zsui;
1555 assert (zei->curDatabaseInfo);
1556 zebraExplain_addAttributeSet (zei, set);
1557 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1558 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1559 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1560 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1562 zsui->info.index_type = index_type;
1563 zsui->info.which = ZEB_SU_SET_USE;
1564 zsui->info.u.su.set = set;
1565 zsui->info.u.su.use = use;
1566 zsui->info.ordinal = (zei->ordinalSU)++;
1567 return zsui->info.ordinal;
1570 int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
1571 const char *index_name)
1573 struct zebSUInfoB *zsui;
1575 assert (zei->curDatabaseInfo);
1576 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1577 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1578 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1579 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1581 zsui->info.index_type = index_type;
1582 zsui->info.which = ZEB_SU_STR;
1583 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1584 zsui->info.ordinal = (zei->ordinalSU)++;
1585 return zsui->info.ordinal;
1588 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1590 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1591 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1592 accessInfo->schemas, oid);
1595 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1597 assert (zei->curDatabaseInfo);
1601 zei->curDatabaseInfo->recordBytes += adjust_num;
1602 zei->curDatabaseInfo->dirty = 1;
1606 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1608 assert (zei->curDatabaseInfo);
1612 zei->curDatabaseInfo->recordCount += adjust_num;
1613 zei->curDatabaseInfo->dirty = 1;
1617 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1623 return zei->runNumber += adjust_num;
1626 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1628 RecordAttr *recordAttr;
1630 if (rec->info[recInfo_attr])
1631 return (RecordAttr *) rec->info[recInfo_attr];
1632 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1633 rec->info[recInfo_attr] = (char *) recordAttr;
1634 rec->size[recInfo_attr] = sizeof(*recordAttr);
1636 recordAttr->recordSize = 0;
1637 recordAttr->recordOffset = 0;
1638 recordAttr->runNumber = zei->runNumber;
1639 recordAttr->staticrank = 0;
1643 static void att_loadset(void *p, const char *n, const char *name)
1645 data1_handle dh = (data1_handle) p;
1646 if (!data1_get_attset (dh, name))
1647 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1650 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1652 if (!zei->curDatabaseInfo)
1654 return zei->curDatabaseInfo->ordinalDatabase;
1657 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1659 res_trav(res, "attset", dh, att_loadset);
1663 zebraExplain_addSU adds to AttributeDetails for a database and
1664 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1665 exist for the database.
1667 If the database doesn't exist globally (in TargetInfo) an
1668 AttributeSetInfo must be added (globally).