1 /* $Id: zinfo.c,v 1.71 2006-11-14 08:12:08 adam Exp $
2 Copyright (C) 1995-2006
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 this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sys/types.h>
29 #include <idzebra/version.h>
36 zinfo_index_category_t cat;
37 #define ZEB_SU_SET_USE 1
45 zint term_occurrences;
49 struct zebSUInfo info;
50 struct zebSUInfoB *next;
53 typedef struct zebAccessObjectB *zebAccessObject;
54 struct zebAccessObjectB {
61 typedef struct zebAccessInfoB *zebAccessInfo;
62 struct zebAccessInfoB {
63 zebAccessObject attributeSetIds;
64 zebAccessObject schemas;
68 struct zebSUInfoB *SUInfo;
72 data1_node *data1_tree;
73 } *zebAttributeDetails;
75 struct zebDatabaseInfoB {
76 zebAttributeDetails attributeDetails;
79 data1_node *data1_database;
80 zint recordCount; /* records in db */
81 zint recordBytes; /* size of records */
82 SYSNO sysno; /* sysno of database info */
83 int readFlag; /* 1: read is needed when referenced; 0 if not */
84 int dirty; /* 1: database is dirty: write is needed */
85 struct zebDatabaseInfoB *next;
86 zebAccessInfo accessInfo;
89 struct zebraExplainAttset {
92 struct zebraExplainAttset *next;
95 struct zebraCategoryListInfo {
98 data1_node *data1_categoryList;
101 struct zebraExplainInfo {
110 struct zebraExplainAttset *attsets;
112 data1_node *data1_target;
113 struct zebraCategoryListInfo *categoryList;
114 struct zebDatabaseInfoB *databaseInfo;
115 struct zebDatabaseInfoB *curDatabaseInfo;
116 zebAccessInfo accessInfo;
117 char date[15]; /* YYYY MMDD HH MM SS */
118 ZebraExplainUpdateFunc *updateFunc;
122 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
123 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
125 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
127 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
130 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
131 struct zebDatabaseInfoB *zdi,
133 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
134 zebAttributeDetails zad,
135 const char *databaseName,
137 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
138 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
141 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
142 struct zebraCategoryListInfo *zcl,
146 static Record createRecord(Records records, SYSNO *sysno)
151 rec = rec_get(records, *sysno);
154 xfree(rec->info[recInfo_storeData]);
158 rec = rec_new(records);
163 rec->info[recInfo_fileType] =
164 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
165 rec->info[recInfo_databaseName] =
166 rec_strdup("IR-Explain-1",
167 &rec->size[recInfo_databaseName]);
172 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
176 zei->updateHandle = handle;
179 struct zebDatabaseInfoB *zdi;
182 /* write each database info record */
183 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
185 zebraExplain_writeDatabase(zei, zdi, 1);
186 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
187 zdi->databaseName, 1);
189 zebraExplain_writeTarget(zei, 1);
190 zebraExplain_writeCategoryList(zei,
193 assert(zei->accessInfo);
194 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
196 zebraExplain_writeAttributeSet(zei, o, 1);
197 for (o = zei->accessInfo->schemas; o; o = o->next)
200 /* zebraExplain_writeSchema(zei, o, 1); */
203 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
205 zebraExplain_writeDatabase(zei, zdi, 0);
206 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
207 zdi->databaseName, 0);
209 zebraExplain_writeTarget(zei, 0);
213 void zebraExplain_close(ZebraExplainInfo zei)
216 yaz_log(YLOG_LOG, "zebraExplain_close");
220 zebraExplain_flush(zei, zei->updateHandle);
221 nmem_destroy(zei->nmem);
224 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
229 for (np = n->child; np; np = np->next)
236 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
238 len = np->child->u.data.len;
241 memcpy(str, np->child->u.data.data, len);
244 oid = odr_getoidbystr_nmem(zei->nmem, str);
246 for (ao = *op; ao; ao = ao->next)
247 if (!oid_oidcmp(oid, ao->oid))
254 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
264 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
265 zebAccessInfo *accessInfo)
271 *accessInfo = (zebAccessInfo)
272 nmem_malloc(zei->nmem, sizeof(**accessInfo));
273 (*accessInfo)->attributeSetIds = NULL;
274 (*accessInfo)->schemas = NULL;
278 if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
280 if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
281 zebraExplain_mergeOids(zei, np,
282 &(*accessInfo)->attributeSetIds);
283 if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
284 zebraExplain_mergeOids(zei, np,
285 &(*accessInfo)->schemas);
294 databaseList (list of databases)
299 targetInfo: TargetInfo
306 dateAdded: 20030630190601
307 dateChanged: 20030630190601
313 oid: 1.2.840.10003.3.2
314 oid: 1.2.840.10003.3.5
315 oid: 1.2.840.10003.3.1
317 oid: 1.2.840.10003.13.1000.81.2
318 oid: 1.2.840.10003.13.2
325 attributeDetailsId: 51
329 attributeDetailsId: 53
332 nextResultSetPosition = 2
335 ZebraExplainInfo zebraExplain_open(
336 Records records, data1_handle dh,
340 ZebraExplainUpdateFunc *updateFunc)
343 ZebraExplainInfo zei;
344 struct zebDatabaseInfoB **zdip;
347 NMEM nmem = nmem_create();
350 yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
352 zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
353 zei->databaseInfo = 0;
354 zei->write_flag = writeFlag;
355 zei->updateHandle = updateHandle;
356 zei->updateFunc = updateFunc;
358 zei->ordinalDatabase = 1;
359 zei->curDatabaseInfo = NULL;
360 zei->records = records;
364 data1_get_absyn (zei->dh, "explain", DATA1_XPATH_INDEXING_DISABLE);
368 zei->categoryList = (struct zebraCategoryListInfo *)
369 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
370 zei->categoryList->sysno = 0;
371 zei->categoryList->dirty = 0;
372 zei->categoryList->data1_categoryList = NULL;
374 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
377 tm = localtime(&our_time);
378 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
379 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
380 tm->tm_hour, tm->tm_min, tm->tm_sec);
382 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
385 zdip = &zei->databaseInfo;
386 trec = rec_get_root(records); /* get "root" record */
391 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
392 if (trec) /* targetInfo already exists ... */
394 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
396 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
398 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
400 if (!zei->data1_target)
403 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
404 nmem_destroy(zei->nmem);
408 data1_pr_tree(zei->dh, zei->data1_target, stderr);
410 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
412 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
415 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
420 node_list = data1_search_tag(zei->dh, node_zebra->child,
423 np = node_list->child;
425 for(; np; np = np->next)
427 data1_node *node_name = NULL;
428 data1_node *node_id = NULL;
429 data1_node *node_aid = NULL;
431 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
433 for(np2 = np->child; np2; np2 = np2->next)
435 if (np2->which != DATA1N_tag)
437 if (!strcmp(np2->u.tag.tag, "name"))
438 node_name = np2->child;
439 else if (!strcmp(np2->u.tag.tag, "id"))
440 node_id = np2->child;
441 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
442 node_aid = np2->child;
444 assert(node_id && node_name && node_aid);
446 *zdip =(struct zebDatabaseInfoB *)
447 nmem_malloc(zei->nmem, sizeof(**zdip));
448 (*zdip)->readFlag = 1;
450 (*zdip)->data1_database = NULL;
451 (*zdip)->recordCount = 0;
452 (*zdip)->recordBytes = 0;
453 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
455 (*zdip)->databaseName = (char *)
456 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
457 memcpy((*zdip)->databaseName, node_name->u.data.data,
458 node_name->u.data.len);
459 (*zdip)->databaseName[node_name->u.data.len] = '\0';
460 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
461 node_id->u.data.len);
462 (*zdip)->attributeDetails = (zebAttributeDetails)
463 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
464 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
465 node_aid->u.data.len);
466 (*zdip)->attributeDetails->readFlag = 1;
467 (*zdip)->attributeDetails->dirty = 0;
468 (*zdip)->attributeDetails->SUInfo = NULL;
470 zdip = &(*zdip)->next;
474 np = data1_search_tag(zei->dh, node_zebra->child,
477 assert (np && np->which == DATA1N_data);
478 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
480 np = data1_search_tag(zei->dh, node_zebra->child,
483 assert (np && np->which == DATA1N_data);
484 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
486 np = data1_search_tag(zei->dh, node_zebra->child,
489 assert (np && np->which == DATA1N_data);
490 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
491 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
496 else /* create initial targetInfo */
498 data1_node *node_tgtinfo;
507 data1_read_sgml(zei->dh, zei->nmem,
508 "<explain><targetInfo>TargetInfo\n"
510 "<namedResultSets>1</>\n"
511 "<multipleDBSearch>1</>\n"
512 "<nicknames><name>Zebra</></>\n"
514 if (!zei->data1_target)
516 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
517 nmem_destroy(zei->nmem);
520 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
522 assert(node_tgtinfo);
524 zebraExplain_initCommonInfo(zei, node_tgtinfo);
525 zebraExplain_initAccessInfo(zei, node_tgtinfo);
527 /* write now because we want to be sure about the sysno */
528 trec = rec_new(records);
531 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
532 nmem_destroy(zei->nmem);
535 trec->info[recInfo_fileType] =
536 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
537 trec->info[recInfo_databaseName] =
538 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
540 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
541 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
542 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
543 trec->size[recInfo_storeData] = sgml_len;
545 rec_put(records, &trec);
549 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
551 if (!zei->categoryList->dirty)
553 struct zebraCategoryListInfo *zcl = zei->categoryList;
557 zcl->data1_categoryList =
558 data1_read_sgml(zei->dh, zei->nmem,
559 "<explain><categoryList>CategoryList\n"
562 if (zcl->data1_categoryList)
564 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
567 zebraExplain_initCommonInfo(zei, node_cl);
574 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
575 zebAttributeDetails zad)
578 struct zebSUInfoB **zsuip = &zad->SUInfo;
579 data1_node *node_adinfo, *node_zebra, *node_list, *np;
582 rec = rec_get(zei->records, zad->sysno);
584 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
586 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
587 "/attributeDetails");
588 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
590 node_list = data1_search_tag(zei->dh, node_zebra->child,
592 for (np = node_list->child; np; np = np->next)
594 data1_node *node_str = NULL;
595 data1_node *node_ordinal = NULL;
596 data1_node *node_type = NULL;
597 data1_node *node_cat = NULL;
598 data1_node *node_doc_occurrences = NULL;
599 data1_node *node_term_occurrences = NULL;
602 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
604 for (np2 = np->child; np2; np2 = np2->next)
606 if (np2->which != DATA1N_tag || !np2->child ||
607 np2->child->which != DATA1N_data)
609 if (!strcmp(np2->u.tag.tag, "str"))
610 node_str = np2->child;
611 else if (!strcmp(np2->u.tag.tag, "ordinal"))
612 node_ordinal = np2->child;
613 else if (!strcmp(np2->u.tag.tag, "type"))
614 node_type = np2->child;
615 else if (!strcmp(np2->u.tag.tag, "cat"))
616 node_cat = np2->child;
617 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
618 node_doc_occurrences = np2->child;
619 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
620 node_term_occurrences = np2->child;
623 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
627 assert(node_ordinal);
629 *zsuip = (struct zebSUInfoB *)
630 nmem_malloc(zei->nmem, sizeof(**zsuip));
632 if (node_type && node_type->u.data.len > 0)
633 (*zsuip)->info.index_type = node_type->u.data.data[0];
636 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
637 (*zsuip)->info.index_type = 'w';
639 if (node_cat && node_cat->u.data.len > 0)
641 zinfo_index_category_t cat;
643 data1_node *np = node_cat;
644 if (!strncmp(np->u.data.data, "index", np->u.data.len))
645 cat = zinfo_index_category_index;
646 else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
647 cat = zinfo_index_category_sort;
648 else if (!strncmp(np->u.data.data, "alwaysmatches",
650 cat = zinfo_index_category_alwaysmatches;
651 else if (!strncmp(np->u.data.data, "anchor",
653 cat = zinfo_index_category_anchor;
656 yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
657 np->u.data.len, np->u.data.data);
658 cat = zinfo_index_category_index;
660 (*zsuip)->info.cat = cat;
663 (*zsuip)->info.cat = zinfo_index_category_index;
665 if (node_doc_occurrences)
667 data1_node *np = node_doc_occurrences;
668 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
671 if (node_term_occurrences)
673 data1_node *np = node_term_occurrences;
674 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
679 (*zsuip)->info.which = ZEB_SU_STR;
681 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
682 node_str->u.data.data,
683 node_str->u.data.len);
687 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
690 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
691 node_ordinal->u.data.len);
692 zsuip = &(*zsuip)->next;
699 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
700 struct zebDatabaseInfoB *zdi)
703 data1_node *node_dbinfo, *node_zebra, *np;
706 rec = rec_get (zei->records, zdi->sysno);
708 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
710 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
712 assert (node_dbinfo);
713 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
715 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
718 && (np = data1_search_tag (zei->dh, node_zebra->child,
720 && np->child && np->child->which == DATA1N_data)
721 zdi->recordBytes = atoi_zn (np->child->u.data.data,
722 np->child->u.data.len);
725 && (np = data1_search_tag (zei->dh, node_zebra->child,
727 && np->child && np->child->which == DATA1N_data)
728 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
729 np->child->u.data.len);
731 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
733 (np = data1_search_tag (zei->dh, np->child,
734 "recordCountActual")) &&
735 np->child->which == DATA1N_data)
737 zdi->recordCount = atoi_zn (np->child->u.data.data,
738 np->child->u.data.len);
744 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
746 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
750 if (*zdip == zei->curDatabaseInfo)
752 struct zebDatabaseInfoB *zdi = *zdip;
756 zei->updateHandle = update_handle;
758 if (zdi->attributeDetails)
760 /* remove attribute details keys and delete it */
761 zebAttributeDetails zad = zdi->attributeDetails;
763 rec = rec_get(zei->records, zad->sysno);
764 (*zei->updateFunc)(zei->updateHandle, rec, 0);
767 /* remove database record keys and delete it */
768 rec = rec_get (zei->records, zdi->sysno);
769 (*zei->updateFunc)(zei->updateHandle, rec, 0);
772 /* remove from list */
775 /* current database is IR-Explain-1 */
778 zdip = &(*zdip)->next;
783 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
785 struct zebDatabaseInfoB *zdi;
786 const char *database_n = strrchr (database, '/');
791 database_n = database;
794 if (zei->curDatabaseInfo &&
795 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
797 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
799 if (!STRCASECMP (zdi->databaseName, database_n))
805 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
810 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
812 zebraExplain_readDatabase (zei, zdi);
814 if (zdi->attributeDetails->readFlag)
817 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
819 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
821 zei->curDatabaseInfo = zdi;
825 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
827 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
828 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
829 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
830 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
833 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
835 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
837 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
841 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
843 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
844 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
845 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
848 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
849 zebAccessInfo accessInfo)
851 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
857 data1_pr_tree (zei->dh, n, stdout);
858 zebra_exit("zebraExplain_updateAccessInfo");
861 if ((p = accessInfo->attributeSetIds))
863 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
864 for (; p; p = p->next)
865 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
867 if ((p = accessInfo->schemas))
869 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
870 for (; p; p = p->next)
871 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
875 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
876 int explain_database)
878 struct zebDatabaseInfoB *zdi;
879 data1_node *node_dbinfo, *node_adinfo;
880 const char *database_n = strrchr (database, '/');
885 database_n = database;
888 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
891 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
893 if (!STRCASECMP (zdi->databaseName, database_n))
898 /* it's new really. make it */
899 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
900 zdi->next = zei->databaseInfo;
901 zei->databaseInfo = zdi;
903 zdi->recordCount = 0;
904 zdi->recordBytes = 0;
906 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
908 zdi->ordinalDatabase = zei->ordinalDatabase++;
910 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
915 zdi->data1_database =
916 data1_read_sgml (zei->dh, zei->nmem,
917 "<explain><databaseInfo>DatabaseInfo\n"
919 if (!zdi->data1_database)
922 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
924 assert (node_dbinfo);
926 zebraExplain_initCommonInfo (zei, node_dbinfo);
927 zebraExplain_initAccessInfo (zei, node_dbinfo);
929 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
930 database, zei->nmem);
932 if (explain_database)
933 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
936 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
939 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
943 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
947 zei->curDatabaseInfo = zdi;
949 zdi->attributeDetails = (zebAttributeDetails)
950 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
951 zdi->attributeDetails->readFlag = 0;
952 zdi->attributeDetails->sysno = 0;
953 zdi->attributeDetails->dirty = 1;
954 zdi->attributeDetails->SUInfo = NULL;
955 zdi->attributeDetails->data1_tree =
956 data1_read_sgml (zei->dh, zei->nmem,
957 "<explain><attributeDetails>AttributeDetails\n"
960 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
961 "/attributeDetails");
962 assert (node_adinfo);
964 zebraExplain_initCommonInfo (zei, node_adinfo);
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;
1043 struct zebSUInfoB *zsui;
1050 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1053 drec = createRecord (zei->records, &zad->sysno);
1056 assert (zad->data1_tree);
1058 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1059 "/attributeDetails");
1060 zebraExplain_updateCommonInfo (zei, node_adinfo);
1062 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1063 databaseName, zei->nmem);
1065 /* extract *searchable* keys from it. We do this here, because
1066 record count, etc. is affected */
1068 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1069 /* zebra info (private) */
1070 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1071 "zebraInfo", node_adinfo);
1072 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1073 "attrlist", node_zebra);
1074 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1076 data1_node *node_attr;
1077 char index_type_str[2];
1079 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1082 index_type_str[0] = zsui->info.index_type;
1083 index_type_str[1] = '\0';
1084 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1085 index_type_str, zei->nmem);
1086 if (zsui->info.which == ZEB_SU_STR)
1088 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1089 zsui->info.u.str, zei->nmem);
1091 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1092 zsui->info.ordinal, zei->nmem);
1094 data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
1095 zsui->info.doc_occurrences, zei->nmem);
1096 data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
1097 zsui->info.term_occurrences, zei->nmem);
1098 switch(zsui->info.cat)
1100 case zinfo_index_category_index:
1101 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1102 "index", zei->nmem); break;
1103 case zinfo_index_category_sort:
1104 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1105 "sort", zei->nmem); break;
1106 case zinfo_index_category_alwaysmatches:
1107 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1108 "alwaysmatches", zei->nmem); break;
1109 case zinfo_index_category_anchor:
1110 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1111 "anchor", zei->nmem); break;
1114 /* convert to "SGML" and write it */
1116 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1118 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1120 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1121 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1122 drec->size[recInfo_storeData] = sgml_len;
1124 rec_put (zei->records, &drec);
1127 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1128 struct zebDatabaseInfoB *zdi,
1134 data1_node *node_dbinfo, *node_count, *node_zebra;
1141 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1143 drec = createRecord (zei->records, &zdi->sysno);
1146 assert (zdi->data1_database);
1148 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1151 assert (node_dbinfo);
1152 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1153 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1155 /* extract *searchable* keys from it. We do this here, because
1156 record count, etc. is affected */
1158 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1160 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1161 "recordCount", node_dbinfo);
1162 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1163 zdi->recordCount, zei->nmem);
1165 /* zebra info (private) */
1166 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1167 "zebraInfo", node_dbinfo);
1168 data1_mk_tag_data_zint (zei->dh, node_zebra,
1169 "recordBytes", zdi->recordBytes, zei->nmem);
1171 data1_mk_tag_data_zint(zei->dh, node_zebra,
1172 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1174 /* convert to "SGML" and write it */
1176 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1178 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1180 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1181 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1182 drec->size[recInfo_storeData] = sgml_len;
1184 rec_put (zei->records, &drec);
1187 static void writeAttributeValues (ZebraExplainInfo zei,
1188 data1_node *node_values,
1189 data1_attset *attset)
1192 data1_attset_child *c;
1197 for (c = attset->children; c; c = c->next)
1198 writeAttributeValues (zei, node_values, c->child);
1199 for (atts = attset->atts; atts; atts = atts->next)
1201 data1_node *node_value;
1203 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1204 0 /* attr */, node_values);
1205 data1_mk_tag_data_text (zei->dh, node_value, "name",
1206 atts->name, zei->nmem);
1207 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1208 0 /* attr */, node_value);
1209 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1210 atts->value, zei->nmem);
1215 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1222 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1223 data1_node *node_values;
1224 struct oident *entp;
1225 struct data1_attset *attset = NULL;
1227 if ((entp = oid_getentbyoid (o->oid)))
1228 attset = data1_attset_search_id (zei->dh, entp->value);
1231 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1232 attset ? attset->name : "<unknown>");
1235 drec = createRecord (zei->records, &o->sysno);
1239 data1_read_sgml (zei->dh, zei->nmem,
1240 "<explain><attributeSetInfo>AttributeSetInfo\n"
1243 node_attinfo = data1_search_tag (zei->dh, node_root,
1244 "/attributeSetInfo");
1246 assert (node_attinfo);
1247 zebraExplain_initCommonInfo (zei, node_attinfo);
1248 zebraExplain_updateCommonInfo (zei, node_attinfo);
1250 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1251 "oid", o->oid, zei->nmem);
1252 if (attset && attset->name)
1253 data1_mk_tag_data_text (zei->dh, node_attinfo,
1254 "name", attset->name, zei->nmem);
1256 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1257 "attributes", node_attinfo);
1258 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1259 "attributeType", node_attributes);
1260 data1_mk_tag_data_text (zei->dh, node_atttype,
1261 "name", "Use", zei->nmem);
1262 data1_mk_tag_data_text (zei->dh, node_atttype,
1263 "description", "Use Attribute", zei->nmem);
1264 data1_mk_tag_data_int (zei->dh, node_atttype,
1265 "type", 1, zei->nmem);
1266 node_values = data1_mk_tag (zei->dh, zei->nmem,
1267 "attributeValues", 0 /* attr */, node_atttype);
1269 writeAttributeValues (zei, node_values, attset);
1271 /* extract *searchable* keys from it. We do this here, because
1272 record count, etc. is affected */
1274 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1275 /* convert to "SGML" and write it */
1277 data1_pr_tree (zei->dh, node_root, stderr);
1279 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1280 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1281 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1282 drec->size[recInfo_storeData] = sgml_len;
1284 rec_put (zei->records, &drec);
1287 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1289 struct zebDatabaseInfoB *zdi;
1290 data1_node *node_tgtinfo, *node_list, *node_zebra;
1299 trec = rec_get_root(zei->records);
1300 xfree (trec->info[recInfo_storeData]);
1302 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1304 assert (node_tgtinfo);
1306 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1307 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1309 /* convert to "SGML" and write it */
1311 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1313 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1314 "zebraInfo", node_tgtinfo);
1315 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1316 ZEBRAVER, zei->nmem);
1317 node_list = data1_mk_tag (zei->dh, zei->nmem,
1318 "databaseList", 0 /* attr */, node_zebra);
1319 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1321 data1_node *node_db;
1322 node_db = data1_mk_tag (zei->dh, zei->nmem,
1323 "database", 0 /* attr */, node_list);
1324 data1_mk_tag_data_text (zei->dh, node_db, "name",
1325 zdi->databaseName, zei->nmem);
1326 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1327 zdi->sysno, zei->nmem);
1328 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1329 zdi->attributeDetails->sysno, zei->nmem);
1331 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1332 zei->ordinalSU, zei->nmem);
1334 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
1335 zei->ordinalDatabase, zei->nmem);
1337 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1338 zei->runNumber, zei->nmem);
1341 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1343 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1345 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1346 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1347 trec->size[recInfo_storeData] = sgml_len;
1349 rec_put (zei->records, &trec);
1352 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
1353 zinfo_index_category_t cat,
1357 struct zebSUInfoB **zsui;
1359 assert (zei->curDatabaseInfo);
1360 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1361 *zsui; zsui = &(*zsui)->next)
1362 if ( (index_type == -1 || (*zsui)->info.index_type == index_type)
1363 && (*zsui)->info.cat == cat
1364 && (*zsui)->info.which == ZEB_SU_STR
1365 && !yaz_matchstr((*zsui)->info.u.str, str))
1367 struct zebSUInfoB *zsui_this = *zsui;
1369 /* take it out of the list and move to front */
1370 *zsui = (*zsui)->next;
1371 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1372 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1374 return zsui_this->info.ordinal;
1379 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1380 int (*f)(void *handle, int ord))
1382 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1385 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1386 for ( ;zsui; zsui = zsui->next)
1387 (*f)(handle, zsui->info.ordinal);
1393 struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
1397 struct zebDatabaseInfoB *zdb;
1399 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1401 struct zebSUInfoB **zsui;
1403 if (zdb->attributeDetails->readFlag)
1404 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1406 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1407 zsui = &(*zsui)->next)
1408 if ((*zsui)->info.ordinal == ord)
1410 struct zebSUInfoB *zsui_this = *zsui;
1412 /* take it out of the list and move to front */
1413 *zsui = (*zsui)->next;
1414 zsui_this->next = zdb->attributeDetails->SUInfo;
1415 zdb->attributeDetails->SUInfo = zsui_this;
1418 zdb->attributeDetails->dirty = 1;
1420 *db = zdb->databaseName;
1429 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1430 int term_delta, int doc_delta)
1432 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1435 zsui->info.term_occurrences += term_delta;
1436 zsui->info.doc_occurrences += doc_delta;
1442 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1443 zint *term_occurrences,
1444 zint *doc_occurrences)
1446 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1449 *term_occurrences = zsui->info.term_occurrences;
1450 *doc_occurrences = zsui->info.doc_occurrences;
1456 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1458 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1460 return zsui->info.doc_occurrences;
1464 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1466 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1468 return zsui->info.term_occurrences;
1472 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1475 const char **string_index)
1477 struct zebSUInfoB *zsui;
1484 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1487 if (zsui->info.which == ZEB_SU_STR)
1489 *string_index = zsui->info.u.str;
1491 *index_type = zsui->info.index_type;
1499 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1500 zebAccessObject *op,
1505 for (ao = *op; ao; ao = ao->next)
1506 if (!oid_oidcmp (oid, ao->oid))
1510 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1513 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1520 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1525 oe.proto = PROTO_Z3950;
1526 oe.oclass = CLASS_ATTSET;
1527 oe.value = (enum oid_value) set;
1529 if (oid_ent_to_oid (&oe, oid))
1531 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1532 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1533 accessInfo->attributeSetIds, oid);
1537 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1538 zinfo_index_category_t cat,
1541 struct zebSUInfoB *zsui;
1543 assert (zei->curDatabaseInfo);
1544 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1545 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1546 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1547 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1549 zsui->info.index_type = index_type;
1550 zsui->info.cat = cat;
1551 zsui->info.doc_occurrences = 0;
1552 zsui->info.term_occurrences = 0;
1553 zsui->info.ordinal = (zei->ordinalSU)++;
1557 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1558 zinfo_index_category_t cat,
1560 const char *index_name)
1562 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1564 zsui->info.which = ZEB_SU_STR;
1565 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1566 return zsui->info.ordinal;
1569 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1571 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1572 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1573 accessInfo->schemas, oid);
1576 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1578 assert (zei->curDatabaseInfo);
1582 zei->curDatabaseInfo->recordBytes += adjust_num;
1583 zei->curDatabaseInfo->dirty = 1;
1587 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1589 assert (zei->curDatabaseInfo);
1593 zei->curDatabaseInfo->recordCount += adjust_num;
1594 zei->curDatabaseInfo->dirty = 1;
1598 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1604 return zei->runNumber += adjust_num;
1607 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1609 RecordAttr *recordAttr;
1611 if (rec->info[recInfo_attr])
1612 return (RecordAttr *) rec->info[recInfo_attr];
1613 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1614 rec->info[recInfo_attr] = (char *) recordAttr;
1615 rec->size[recInfo_attr] = sizeof(*recordAttr);
1617 recordAttr->recordSize = 0;
1618 recordAttr->recordOffset = 0;
1619 recordAttr->runNumber = zei->runNumber;
1620 recordAttr->staticrank = 0;
1624 static void att_loadset(void *p, const char *n, const char *name)
1626 data1_handle dh = (data1_handle) p;
1627 if (!data1_get_attset (dh, name))
1628 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1631 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1633 if (!zei->curDatabaseInfo)
1635 return zei->curDatabaseInfo->ordinalDatabase;
1638 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1640 res_trav(res, "attset", dh, att_loadset);
1644 zebraExplain_addSU adds to AttributeDetails for a database and
1645 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1646 exist for the database.
1648 If the database doesn't exist globally (in TargetInfo) an
1649 AttributeSetInfo must be added (globally).
1654 * indent-tabs-mode: nil
1656 * vim: shiftwidth=4 tabstop=8 expandtab