1 /* $Id: zinfo.c,v 1.79 2007-10-29 11:10:43 adam Exp $
2 Copyright (C) 1995-2007
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 zint 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, zint *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 = 0;
274 (*accessInfo)->schemas = 0;
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 = 0;
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 = 0;
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,
414 yaz_log(YLOG_FATAL, "Node node_tgtinfo missing");
415 nmem_destroy(zei->nmem);
418 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
421 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
425 yaz_log(YLOG_FATAL, "Node node_zebra missing");
426 nmem_destroy(zei->nmem);
432 node_list = data1_search_tag(zei->dh, node_zebra->child,
435 np = node_list->child;
437 for(; np; np = np->next)
439 data1_node *node_name = 0;
440 data1_node *node_id = 0;
441 data1_node *node_aid = 0;
443 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
445 for(np2 = np->child; np2; np2 = np2->next)
447 if (np2->which != DATA1N_tag)
449 if (!strcmp(np2->u.tag.tag, "name"))
450 node_name = np2->child;
451 else if (!strcmp(np2->u.tag.tag, "id"))
452 node_id = np2->child;
453 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
454 node_aid = np2->child;
456 assert(node_id && node_name && node_aid);
458 *zdip =(struct zebDatabaseInfoB *)
459 nmem_malloc(zei->nmem, sizeof(**zdip));
460 (*zdip)->readFlag = 1;
462 (*zdip)->data1_database = 0;
463 (*zdip)->recordCount = 0;
464 (*zdip)->recordBytes = 0;
465 zebraExplain_mergeAccessInfo(zei, 0, &(*zdip)->accessInfo);
467 (*zdip)->databaseName = (char *)
468 nmem_malloc(zei->nmem, 1+node_name->u.data.len);
469 memcpy((*zdip)->databaseName, node_name->u.data.data,
470 node_name->u.data.len);
471 (*zdip)->databaseName[node_name->u.data.len] = '\0';
472 (*zdip)->sysno = atoi_zn(node_id->u.data.data,
473 node_id->u.data.len);
474 (*zdip)->attributeDetails = (zebAttributeDetails)
475 nmem_malloc(zei->nmem, sizeof(*(*zdip)->attributeDetails));
476 (*zdip)->attributeDetails->sysno = atoi_zn(node_aid->u.data.data,
477 node_aid->u.data.len);
478 (*zdip)->attributeDetails->readFlag = 1;
479 (*zdip)->attributeDetails->dirty = 0;
480 (*zdip)->attributeDetails->SUInfo = 0;
482 zdip = &(*zdip)->next;
486 np = data1_search_tag(zei->dh, node_zebra->child,
489 assert(np && np->which == DATA1N_data);
490 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
492 np = data1_search_tag(zei->dh, node_zebra->child,
495 assert(np && np->which == DATA1N_data);
496 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
498 np = data1_search_tag(zei->dh, node_zebra->child,
501 assert(np && np->which == DATA1N_data);
502 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
503 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
508 else /* create initial targetInfo */
510 data1_node *node_tgtinfo;
519 data1_read_sgml(zei->dh, zei->nmem,
520 "<explain><targetInfo>TargetInfo\n"
522 "<namedResultSets>1</>\n"
523 "<multipleDBSearch>1</>\n"
524 "<nicknames><name>Zebra</></>\n"
526 if (!zei->data1_target)
528 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
529 nmem_destroy(zei->nmem);
532 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
534 assert(node_tgtinfo);
536 zebraExplain_initCommonInfo(zei, node_tgtinfo);
537 zebraExplain_initAccessInfo(zei, node_tgtinfo);
539 /* write now because we want to be sure about the sysno */
540 trec = rec_new(records);
543 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
544 nmem_destroy(zei->nmem);
547 trec->info[recInfo_fileType] =
548 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
549 trec->info[recInfo_databaseName] =
550 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
552 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
553 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
554 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
555 trec->size[recInfo_storeData] = sgml_len;
557 rec_put(records, &trec);
561 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
563 if (!zei->categoryList->dirty)
565 struct zebraCategoryListInfo *zcl = zei->categoryList;
569 zcl->data1_categoryList =
570 data1_read_sgml(zei->dh, zei->nmem,
571 "<explain><categoryList>CategoryList\n"
574 if (zcl->data1_categoryList)
576 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
579 zebraExplain_initCommonInfo(zei, node_cl);
586 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
587 zebAttributeDetails zad)
590 struct zebSUInfoB **zsuip = &zad->SUInfo;
591 data1_node *node_adinfo, *node_zebra, *node_list, *np;
594 rec = rec_get(zei->records, zad->sysno);
596 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
598 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
599 "/attributeDetails");
600 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
602 node_list = data1_search_tag(zei->dh, node_zebra->child,
604 for (np = node_list->child; np; np = np->next)
606 data1_node *node_str = 0;
607 data1_node *node_ordinal = 0;
608 data1_node *node_type = 0;
609 data1_node *node_cat = 0;
610 data1_node *node_doc_occurrences = 0;
611 data1_node *node_term_occurrences = 0;
614 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
616 for (np2 = np->child; np2; np2 = np2->next)
618 if (np2->which != DATA1N_tag || !np2->child ||
619 np2->child->which != DATA1N_data)
621 if (!strcmp(np2->u.tag.tag, "str"))
622 node_str = np2->child;
623 else if (!strcmp(np2->u.tag.tag, "ordinal"))
624 node_ordinal = np2->child;
625 else if (!strcmp(np2->u.tag.tag, "type"))
626 node_type = np2->child;
627 else if (!strcmp(np2->u.tag.tag, "cat"))
628 node_cat = np2->child;
629 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
630 node_doc_occurrences = np2->child;
631 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
632 node_term_occurrences = np2->child;
635 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
639 assert(node_ordinal);
641 *zsuip = (struct zebSUInfoB *)
642 nmem_malloc(zei->nmem, sizeof(**zsuip));
644 if (node_type && node_type->u.data.len > 0)
645 (*zsuip)->info.index_type = node_type->u.data.data[0];
648 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
649 (*zsuip)->info.index_type = 'w';
651 if (node_cat && node_cat->u.data.len > 0)
653 zinfo_index_category_t cat;
655 data1_node *np = node_cat;
656 if (!strncmp(np->u.data.data, "index", np->u.data.len))
657 cat = zinfo_index_category_index;
658 else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
659 cat = zinfo_index_category_sort;
660 else if (!strncmp(np->u.data.data, "alwaysmatches",
662 cat = zinfo_index_category_alwaysmatches;
663 else if (!strncmp(np->u.data.data, "anchor",
665 cat = zinfo_index_category_anchor;
668 yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
669 np->u.data.len, np->u.data.data);
670 cat = zinfo_index_category_index;
672 (*zsuip)->info.cat = cat;
675 (*zsuip)->info.cat = zinfo_index_category_index;
677 if (node_doc_occurrences)
679 data1_node *np = node_doc_occurrences;
680 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
683 if (node_term_occurrences)
685 data1_node *np = node_term_occurrences;
686 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
691 (*zsuip)->info.which = ZEB_SU_STR;
693 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
694 node_str->u.data.data,
695 node_str->u.data.len);
699 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
702 (*zsuip)->info.ordinal = atoi_n(node_ordinal->u.data.data,
703 node_ordinal->u.data.len);
704 zsuip = &(*zsuip)->next;
711 static void zebraExplain_readDatabase(ZebraExplainInfo zei,
712 struct zebDatabaseInfoB *zdi)
715 data1_node *node_dbinfo, *node_zebra, *np;
718 rec = rec_get(zei->records, zdi->sysno);
720 zdi->data1_database = read_sgml_rec(zei->dh, zei->nmem, rec);
722 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
725 zebraExplain_mergeAccessInfo(zei, node_dbinfo, &zdi->accessInfo);
727 node_zebra = data1_search_tag(zei->dh, node_dbinfo->child,
730 && (np = data1_search_tag(zei->dh, node_zebra->child,
732 && np->child && np->child->which == DATA1N_data)
733 zdi->recordBytes = atoi_zn(np->child->u.data.data,
734 np->child->u.data.len);
737 && (np = data1_search_tag(zei->dh, node_zebra->child,
739 && np->child && np->child->which == DATA1N_data)
740 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
741 np->child->u.data.len);
743 if ((np = data1_search_tag(zei->dh, node_dbinfo->child,
745 (np = data1_search_tag(zei->dh, np->child,
746 "recordCountActual")) &&
747 np->child->which == DATA1N_data)
749 zdi->recordCount = atoi_zn(np->child->u.data.data,
750 np->child->u.data.len);
756 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
758 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
762 if (*zdip == zei->curDatabaseInfo)
764 struct zebDatabaseInfoB *zdi = *zdip;
768 zei->updateHandle = update_handle;
770 if (zdi->attributeDetails)
772 /* remove attribute details keys and delete it */
773 zebAttributeDetails zad = zdi->attributeDetails;
775 rec = rec_get(zei->records, zad->sysno);
776 (*zei->updateFunc)(zei->updateHandle, rec, 0);
779 /* remove database record keys and delete it */
780 rec = rec_get(zei->records, zdi->sysno);
781 (*zei->updateFunc)(zei->updateHandle, rec, 0);
784 /* remove from list */
787 /* current database is IR-Explain-1 */
790 zdip = &(*zdip)->next;
795 int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
797 struct zebDatabaseInfoB *zdi;
798 const char *database_n = strrchr(database, '/');
803 database_n = database;
806 if (zei->curDatabaseInfo &&
807 !STRCASECMP(zei->curDatabaseInfo->databaseName, database))
809 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
811 if (!STRCASECMP(zdi->databaseName, database_n))
817 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
822 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
824 zebraExplain_readDatabase(zei, zdi);
826 if (zdi->attributeDetails->readFlag)
829 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
831 zebraExplain_readAttributeDetails(zei, zdi->attributeDetails);
833 zei->curDatabaseInfo = zdi;
837 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n)
839 data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "commonInfo", 0, n);
840 data1_mk_tag_data_text(zei->dh, c, "dateAdded", zei->date, zei->nmem);
841 data1_mk_tag_data_text(zei->dh, c, "dateChanged", zei->date, zei->nmem);
842 data1_mk_tag_data_text(zei->dh, c, "languageCode", "EN", zei->nmem);
845 static void zebraExplain_updateCommonInfo(ZebraExplainInfo zei, data1_node *n)
847 data1_node *c = data1_search_tag(zei->dh, n->child, "commonInfo");
849 data1_mk_tag_data_text_uni(zei->dh, c, "dateChanged", zei->date,
853 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n)
855 data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "accessInfo", 0, n);
856 data1_node *d = data1_mk_tag(zei->dh, zei->nmem, "unitSystems", 0, c);
857 data1_mk_tag_data_text(zei->dh, d, "string", "ISO", zei->nmem);
860 static void zebraExplain_updateAccessInfo(ZebraExplainInfo zei, data1_node *n,
861 zebAccessInfo accessInfo)
863 data1_node *c = data1_search_tag(zei->dh, n->child, "accessInfo");
869 data1_pr_tree(zei->dh, n, stdout);
870 zebra_exit("zebraExplain_updateAccessInfo");
873 if ((p = accessInfo->attributeSetIds))
875 d = data1_mk_tag_uni(zei->dh, zei->nmem, "attributeSetIds", c);
876 for (; p; p = p->next)
877 data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
879 if ((p = accessInfo->schemas))
881 d = data1_mk_tag_uni(zei->dh, zei->nmem, "schemas", c);
882 for (; p; p = p->next)
883 data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
887 int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database,
888 int explain_database)
890 struct zebDatabaseInfoB *zdi;
891 data1_node *node_dbinfo, *node_adinfo;
892 const char *database_n = strrchr(database, '/');
897 database_n = database;
900 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
903 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
905 if (!STRCASECMP(zdi->databaseName, database_n))
910 /* it's new really. make it */
911 zdi = (struct zebDatabaseInfoB *) nmem_malloc(zei->nmem, sizeof(*zdi));
912 zdi->next = zei->databaseInfo;
913 zei->databaseInfo = zdi;
915 zdi->recordCount = 0;
916 zdi->recordBytes = 0;
918 zdi->databaseName = nmem_strdup(zei->nmem, database_n);
920 zdi->ordinalDatabase = zei->ordinalDatabase++;
922 zebraExplain_mergeAccessInfo(zei, 0, &zdi->accessInfo);
927 zdi->data1_database =
928 data1_read_sgml(zei->dh, zei->nmem,
929 "<explain><databaseInfo>DatabaseInfo\n"
931 if (!zdi->data1_database)
934 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
938 zebraExplain_initCommonInfo(zei, node_dbinfo);
939 zebraExplain_initAccessInfo(zei, node_dbinfo);
941 data1_mk_tag_data_text(zei->dh, node_dbinfo, "name",
942 database, zei->nmem);
944 if (explain_database)
945 data1_mk_tag_data_text(zei->dh, node_dbinfo, "explainDatabase",
948 data1_mk_tag_data_text(zei->dh, node_dbinfo, "userFee",
951 data1_mk_tag_data_text(zei->dh, node_dbinfo, "available",
955 data1_pr_tree(zei->dh, zdi->data1_database, stderr);
959 zei->curDatabaseInfo = zdi;
961 zdi->attributeDetails = (zebAttributeDetails)
962 nmem_malloc(zei->nmem, sizeof(*zdi->attributeDetails));
963 zdi->attributeDetails->readFlag = 0;
964 zdi->attributeDetails->sysno = 0;
965 zdi->attributeDetails->dirty = 1;
966 zdi->attributeDetails->SUInfo = 0;
967 zdi->attributeDetails->data1_tree =
968 data1_read_sgml(zei->dh, zei->nmem,
969 "<explain><attributeDetails>AttributeDetails\n"
972 node_adinfo = data1_search_tag(zei->dh, zdi->attributeDetails->data1_tree,
973 "/attributeDetails");
976 zebraExplain_initCommonInfo(zei, node_adinfo);
978 data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
984 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
985 struct zebraCategoryListInfo *zcl,
992 data1_node *node_ci, *node_categoryList;
994 static char *category[] = {
1006 node_categoryList = zcl->data1_categoryList;
1009 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
1012 drec = createRecord(zei->records, &sysno);
1016 node_ci = data1_search_tag(zei->dh, node_categoryList,
1019 node_ci = data1_mk_tag(zei->dh, zei->nmem, "categories", 0 /* attr */,
1023 for (i = 0; category[i]; i++)
1025 data1_node *node_cat = data1_mk_tag(zei->dh, zei->nmem, "category",
1026 0 /* attr */, node_ci);
1028 data1_mk_tag_data_text(zei->dh, node_cat, "name",
1029 category[i], zei->nmem);
1031 /* extract *searchable* keys from it. We do this here, because
1032 record count, etc. is affected */
1034 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1036 /* convert to "SGML" and write it */
1038 data1_pr_tree(zei->dh, node_categoryList, stderr);
1040 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1041 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1042 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1043 drec->size[recInfo_storeData] = sgml_len;
1045 rec_put(zei->records, &drec);
1048 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
1049 zebAttributeDetails zad,
1050 const char *databaseName,
1056 data1_node *node_adinfo, *node_list, *node_zebra;
1057 struct zebSUInfoB *zsui;
1064 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1065 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1068 drec = createRecord(zei->records, &zad->sysno);
1071 assert(zad->data1_tree);
1073 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
1074 "/attributeDetails");
1075 zebraExplain_updateCommonInfo(zei, node_adinfo);
1077 /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
1078 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1079 "zebraInfo", node_adinfo);
1081 /* extract *searchable* keys from it. We do this here, because
1082 record count, etc. is affected */
1084 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1085 node_list = data1_mk_tag_uni(zei->dh, zei->nmem,
1086 "attrlist", node_zebra);
1087 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1089 data1_node *node_attr;
1090 char index_type_str[2];
1092 node_attr = data1_mk_tag(zei->dh, zei->nmem, "attr", 0 /* attr */,
1095 index_type_str[0] = zsui->info.index_type;
1096 index_type_str[1] = '\0';
1097 data1_mk_tag_data_text(zei->dh, node_attr, "type",
1098 index_type_str, zei->nmem);
1099 if (zsui->info.which == ZEB_SU_STR)
1101 data1_mk_tag_data_text(zei->dh, node_attr, "str",
1102 zsui->info.u.str, zei->nmem);
1104 data1_mk_tag_data_int(zei->dh, node_attr, "ordinal",
1105 zsui->info.ordinal, zei->nmem);
1107 data1_mk_tag_data_zint(zei->dh, node_attr, "dococcurrences",
1108 zsui->info.doc_occurrences, zei->nmem);
1109 data1_mk_tag_data_zint(zei->dh, node_attr, "termoccurrences",
1110 zsui->info.term_occurrences, zei->nmem);
1111 switch(zsui->info.cat)
1113 case zinfo_index_category_index:
1114 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1115 "index", zei->nmem); break;
1116 case zinfo_index_category_sort:
1117 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1118 "sort", zei->nmem); break;
1119 case zinfo_index_category_alwaysmatches:
1120 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1121 "alwaysmatches", zei->nmem); break;
1122 case zinfo_index_category_anchor:
1123 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1124 "anchor", zei->nmem); break;
1127 /* convert to "SGML" and write it */
1129 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1131 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1133 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1134 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1135 drec->size[recInfo_storeData] = sgml_len;
1137 rec_put(zei->records, &drec);
1140 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
1141 struct zebDatabaseInfoB *zdi,
1147 data1_node *node_dbinfo, *node_count, *node_zebra;
1154 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1156 drec = createRecord(zei->records, &zdi->sysno);
1159 assert(zdi->data1_database);
1161 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
1164 assert(node_dbinfo);
1165 zebraExplain_updateCommonInfo(zei, node_dbinfo);
1166 zebraExplain_updateAccessInfo(zei, node_dbinfo, zdi->accessInfo);
1169 node_count = data1_mk_tag_uni(zei->dh, zei->nmem,
1170 "recordCount", node_dbinfo);
1171 data1_mk_tag_data_zint(zei->dh, node_count, "recordCountActual",
1172 zdi->recordCount, zei->nmem);
1174 /* zebra info (private) */
1175 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1176 "zebraInfo", node_dbinfo);
1178 /* extract *searchable* keys from it. We do this here, because
1179 record count, etc. is affected */
1181 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1182 data1_mk_tag_data_zint(zei->dh, node_zebra,
1183 "recordBytes", zdi->recordBytes, zei->nmem);
1185 data1_mk_tag_data_zint(zei->dh, node_zebra,
1186 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1188 /* convert to "SGML" and write it */
1190 data1_pr_tree(zei->dh, zdi->data1_database, stderr);
1192 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1194 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1195 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1196 drec->size[recInfo_storeData] = sgml_len;
1198 rec_put(zei->records, &drec);
1201 static void writeAttributeValues(ZebraExplainInfo zei,
1202 data1_node *node_values,
1203 data1_attset *attset)
1206 data1_attset_child *c;
1211 for (c = attset->children; c; c = c->next)
1212 writeAttributeValues(zei, node_values, c->child);
1213 for (atts = attset->atts; atts; atts = atts->next)
1215 data1_node *node_value;
1217 node_value = data1_mk_tag(zei->dh, zei->nmem, "attributeValue",
1218 0 /* attr */, node_values);
1219 data1_mk_tag_data_text(zei->dh, node_value, "name",
1220 atts->name, zei->nmem);
1221 node_value = data1_mk_tag(zei->dh, zei->nmem, "value",
1222 0 /* attr */, node_value);
1223 data1_mk_tag_data_int(zei->dh, node_value, "numeric",
1224 atts->value, zei->nmem);
1229 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
1236 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1237 data1_node *node_values;
1238 struct data1_attset *attset = 0;
1241 attset = data1_attset_search_id(zei->dh, o->oid);
1244 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1245 attset ? attset->name : "<unknown>");
1248 drec = createRecord(zei->records, &o->sysno);
1252 data1_read_sgml(zei->dh, zei->nmem,
1253 "<explain><attributeSetInfo>AttributeSetInfo\n"
1256 node_attinfo = data1_search_tag(zei->dh, node_root,
1257 "/attributeSetInfo");
1259 assert(node_attinfo);
1260 zebraExplain_initCommonInfo(zei, node_attinfo);
1261 zebraExplain_updateCommonInfo(zei, node_attinfo);
1263 data1_mk_tag_data_oid(zei->dh, node_attinfo,
1264 "oid", o->oid, zei->nmem);
1265 if (attset && attset->name)
1266 data1_mk_tag_data_text(zei->dh, node_attinfo,
1267 "name", attset->name, zei->nmem);
1269 node_attributes = data1_mk_tag_uni(zei->dh, zei->nmem,
1270 "attributes", node_attinfo);
1271 node_atttype = data1_mk_tag_uni(zei->dh, zei->nmem,
1272 "attributeType", node_attributes);
1273 data1_mk_tag_data_text(zei->dh, node_atttype,
1274 "name", "Use", zei->nmem);
1275 data1_mk_tag_data_text(zei->dh, node_atttype,
1276 "description", "Use Attribute", zei->nmem);
1277 data1_mk_tag_data_int(zei->dh, node_atttype,
1278 "type", 1, zei->nmem);
1279 node_values = data1_mk_tag(zei->dh, zei->nmem,
1280 "attributeValues", 0 /* attr */, node_atttype);
1282 writeAttributeValues(zei, node_values, attset);
1284 /* extract *searchable* keys from it. We do this here, because
1285 record count, etc. is affected */
1287 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1288 /* convert to "SGML" and write it */
1290 data1_pr_tree(zei->dh, node_root, stderr);
1292 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1293 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1294 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1295 drec->size[recInfo_storeData] = sgml_len;
1297 rec_put(zei->records, &drec);
1300 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush)
1302 struct zebDatabaseInfoB *zdi;
1303 data1_node *node_tgtinfo, *node_list, *node_zebra;
1312 trec = rec_get_root(zei->records);
1313 xfree(trec->info[recInfo_storeData]);
1315 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
1317 assert(node_tgtinfo);
1319 zebraExplain_updateCommonInfo(zei, node_tgtinfo);
1320 zebraExplain_updateAccessInfo(zei, node_tgtinfo, zei->accessInfo);
1322 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1323 "zebraInfo", node_tgtinfo);
1324 /* convert to "SGML" and write it */
1326 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1328 data1_mk_tag_data_text(zei->dh, node_zebra, "version",
1329 ZEBRAVER, zei->nmem);
1330 node_list = data1_mk_tag(zei->dh, zei->nmem,
1331 "databaseList", 0 /* attr */, node_zebra);
1332 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1334 data1_node *node_db;
1335 node_db = data1_mk_tag(zei->dh, zei->nmem,
1336 "database", 0 /* attr */, node_list);
1337 data1_mk_tag_data_text(zei->dh, node_db, "name",
1338 zdi->databaseName, zei->nmem);
1339 data1_mk_tag_data_zint(zei->dh, node_db, "id",
1340 zdi->sysno, zei->nmem);
1341 data1_mk_tag_data_zint(zei->dh, node_db, "attributeDetailsId",
1342 zdi->attributeDetails->sysno, zei->nmem);
1344 data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalSU",
1345 zei->ordinalSU, zei->nmem);
1347 data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalDatabase",
1348 zei->ordinalDatabase, zei->nmem);
1350 data1_mk_tag_data_zint(zei->dh, node_zebra, "runNumber",
1351 zei->runNumber, zei->nmem);
1354 data1_pr_tree(zei->dh, zei->data1_target, stderr);
1356 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1358 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1359 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
1360 trec->size[recInfo_storeData] = sgml_len;
1362 rec_put(zei->records, &trec);
1365 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
1366 zinfo_index_category_t cat,
1370 struct zebSUInfoB **zsui;
1372 assert(zei->curDatabaseInfo);
1373 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1374 *zsui; zsui = &(*zsui)->next)
1375 if ( (index_type == -1 || (*zsui)->info.index_type == index_type)
1376 && (*zsui)->info.cat == cat
1377 && (*zsui)->info.which == ZEB_SU_STR
1378 && !yaz_matchstr((*zsui)->info.u.str, str))
1380 struct zebSUInfoB *zsui_this = *zsui;
1382 /* take it out of the list and move to front */
1383 *zsui = (*zsui)->next;
1384 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1385 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1387 return zsui_this->info.ordinal;
1392 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1393 int (*f)(void *handle, int ord))
1395 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1398 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1399 for ( ;zsui; zsui = zsui->next)
1400 (*f)(handle, zsui->info.ordinal);
1406 struct zebSUInfoB *zebraExplain_get_sui_info(ZebraExplainInfo zei, int ord,
1410 struct zebDatabaseInfoB *zdb;
1412 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1414 struct zebSUInfoB **zsui;
1416 if (zdb->attributeDetails->readFlag)
1417 zebraExplain_readAttributeDetails(zei, zdb->attributeDetails);
1419 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1420 zsui = &(*zsui)->next)
1421 if ((*zsui)->info.ordinal == ord)
1423 struct zebSUInfoB *zsui_this = *zsui;
1425 /* take it out of the list and move to front */
1426 *zsui = (*zsui)->next;
1427 zsui_this->next = zdb->attributeDetails->SUInfo;
1428 zdb->attributeDetails->SUInfo = zsui_this;
1431 zdb->attributeDetails->dirty = 1;
1433 *db = zdb->databaseName;
1442 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1443 int term_delta, int doc_delta)
1445 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1448 zsui->info.term_occurrences += term_delta;
1449 zsui->info.doc_occurrences += doc_delta;
1455 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1456 zint *term_occurrences,
1457 zint *doc_occurrences)
1459 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1462 *term_occurrences = zsui->info.term_occurrences;
1463 *doc_occurrences = zsui->info.doc_occurrences;
1469 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1471 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1473 return zsui->info.doc_occurrences;
1477 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1479 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1481 return zsui->info.term_occurrences;
1485 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1488 const char **string_index)
1490 struct zebSUInfoB *zsui;
1497 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1500 if (zsui->info.which == ZEB_SU_STR)
1502 *string_index = zsui->info.u.str;
1504 *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 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1534 zinfo_index_category_t cat,
1537 struct zebSUInfoB *zsui;
1539 assert(zei->curDatabaseInfo);
1540 zsui = (struct zebSUInfoB *) nmem_malloc(zei->nmem, sizeof(*zsui));
1541 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1542 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1543 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1545 zsui->info.index_type = index_type;
1546 zsui->info.cat = cat;
1547 zsui->info.doc_occurrences = 0;
1548 zsui->info.term_occurrences = 0;
1549 zsui->info.ordinal = (zei->ordinalSU)++;
1553 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1554 zinfo_index_category_t cat,
1556 const char *index_name)
1558 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1560 zsui->info.which = ZEB_SU_STR;
1561 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1562 return zsui->info.ordinal;
1565 void zebraExplain_addSchema(ZebraExplainInfo zei, Odr_oid *oid)
1567 zebraExplain_announceOid(zei, &zei->accessInfo->schemas, oid);
1568 zebraExplain_announceOid(zei, &zei->curDatabaseInfo->
1569 accessInfo->schemas, oid);
1572 void zebraExplain_recordBytesIncrement(ZebraExplainInfo zei, int adjust_num)
1574 assert(zei->curDatabaseInfo);
1578 zei->curDatabaseInfo->recordBytes += adjust_num;
1579 zei->curDatabaseInfo->dirty = 1;
1583 void zebraExplain_recordCountIncrement(ZebraExplainInfo zei, int adjust_num)
1585 assert(zei->curDatabaseInfo);
1589 zei->curDatabaseInfo->recordCount += adjust_num;
1590 zei->curDatabaseInfo->dirty = 1;
1594 zint zebraExplain_runNumberIncrement(ZebraExplainInfo zei, int adjust_num)
1600 return zei->runNumber += adjust_num;
1603 RecordAttr *rec_init_attr(ZebraExplainInfo zei, Record rec)
1605 RecordAttr *recordAttr;
1607 if (rec->info[recInfo_attr])
1608 return (RecordAttr *) rec->info[recInfo_attr];
1609 recordAttr = (RecordAttr *) xmalloc(sizeof(*recordAttr));
1611 memset(recordAttr, '\0', sizeof(*recordAttr));
1612 rec->info[recInfo_attr] = (char *) recordAttr;
1613 rec->size[recInfo_attr] = sizeof(*recordAttr);
1615 recordAttr->recordSize = 0;
1616 recordAttr->recordOffset = 0;
1617 recordAttr->runNumber = zei->runNumber;
1618 recordAttr->staticrank = 0;
1622 static void att_loadset(void *p, const char *n, const char *name)
1624 data1_handle dh = (data1_handle) p;
1625 if (!data1_get_attset(dh, name))
1626 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1629 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1631 if (!zei->curDatabaseInfo)
1633 return zei->curDatabaseInfo->ordinalDatabase;
1636 void zebraExplain_loadAttsets(data1_handle dh, Res res)
1638 res_trav(res, "attset", dh, att_loadset);
1642 zebraExplain_addSU adds to AttributeDetails for a database and
1643 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1644 exist for the database.
1646 If the database doesn't exist globally (in TargetInfo) an
1647 AttributeSetInfo must be added (globally).
1652 * indent-tabs-mode: nil
1654 * vim: shiftwidth=4 tabstop=8 expandtab