1 /* $Id: zinfo.c,v 1.80 2007-10-29 16:57:53 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;
40 zint term_occurrences;
44 struct zebSUInfo info;
45 struct zebSUInfoB *next;
48 typedef struct zebAccessObjectB *zebAccessObject;
49 struct zebAccessObjectB {
56 typedef struct zebAccessInfoB *zebAccessInfo;
57 struct zebAccessInfoB {
58 zebAccessObject attributeSetIds;
59 zebAccessObject schemas;
63 struct zebSUInfoB *SUInfo;
67 data1_node *data1_tree;
68 } *zebAttributeDetails;
70 struct zebDatabaseInfoB {
71 zebAttributeDetails attributeDetails;
74 data1_node *data1_database;
75 zint recordCount; /* records in db */
76 zint recordBytes; /* size of records */
77 zint sysno; /* sysno of database info */
78 int readFlag; /* 1: read is needed when referenced; 0 if not */
79 int dirty; /* 1: database is dirty: write is needed */
80 struct zebDatabaseInfoB *next;
81 zebAccessInfo accessInfo;
84 struct zebraExplainAttset {
87 struct zebraExplainAttset *next;
90 struct zebraCategoryListInfo {
93 data1_node *data1_categoryList;
96 struct zebraExplainInfo {
105 struct zebraExplainAttset *attsets;
107 data1_node *data1_target;
108 struct zebraCategoryListInfo *categoryList;
109 struct zebDatabaseInfoB *databaseInfo;
110 struct zebDatabaseInfoB *curDatabaseInfo;
111 zebAccessInfo accessInfo;
112 char date[15]; /* YYYY MMDD HH MM SS */
113 ZebraExplainUpdateFunc *updateFunc;
117 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
118 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
120 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
122 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
125 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
126 struct zebDatabaseInfoB *zdi,
128 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
129 zebAttributeDetails zad,
130 const char *databaseName,
132 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
133 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
136 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
137 struct zebraCategoryListInfo *zcl,
141 static Record createRecord(Records records, zint *sysno)
146 rec = rec_get(records, *sysno);
149 xfree(rec->info[recInfo_storeData]);
153 rec = rec_new(records);
158 rec->info[recInfo_fileType] =
159 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
160 rec->info[recInfo_databaseName] =
161 rec_strdup("IR-Explain-1",
162 &rec->size[recInfo_databaseName]);
167 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
171 zei->updateHandle = handle;
174 struct zebDatabaseInfoB *zdi;
177 /* write each database info record */
178 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
180 zebraExplain_writeDatabase(zei, zdi, 1);
181 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
182 zdi->databaseName, 1);
184 zebraExplain_writeTarget(zei, 1);
185 zebraExplain_writeCategoryList(zei,
188 assert(zei->accessInfo);
189 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
191 zebraExplain_writeAttributeSet(zei, o, 1);
192 for (o = zei->accessInfo->schemas; o; o = o->next)
195 /* zebraExplain_writeSchema(zei, o, 1); */
198 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
200 zebraExplain_writeDatabase(zei, zdi, 0);
201 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
202 zdi->databaseName, 0);
204 zebraExplain_writeTarget(zei, 0);
208 void zebraExplain_close(ZebraExplainInfo zei)
211 yaz_log(YLOG_LOG, "zebraExplain_close");
215 zebraExplain_flush(zei, zei->updateHandle);
216 nmem_destroy(zei->nmem);
219 void zebraExplain_mergeOids(ZebraExplainInfo zei, data1_node *n,
224 for (np = n->child; np; np = np->next)
231 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
233 len = np->child->u.data.len;
236 memcpy(str, np->child->u.data.data, len);
239 oid = odr_getoidbystr_nmem(zei->nmem, str);
241 for (ao = *op; ao; ao = ao->next)
242 if (!oid_oidcmp(oid, ao->oid))
249 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
259 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
260 zebAccessInfo *accessInfo)
266 *accessInfo = (zebAccessInfo)
267 nmem_malloc(zei->nmem, sizeof(**accessInfo));
268 (*accessInfo)->attributeSetIds = 0;
269 (*accessInfo)->schemas = 0;
273 if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
275 if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
276 zebraExplain_mergeOids(zei, np,
277 &(*accessInfo)->attributeSetIds);
278 if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
279 zebraExplain_mergeOids(zei, np,
280 &(*accessInfo)->schemas);
289 databaseList (list of databases)
294 targetInfo: TargetInfo
301 dateAdded: 20030630190601
302 dateChanged: 20030630190601
308 oid: 1.2.840.10003.3.2
309 oid: 1.2.840.10003.3.5
310 oid: 1.2.840.10003.3.1
312 oid: 1.2.840.10003.13.1000.81.2
313 oid: 1.2.840.10003.13.2
320 attributeDetailsId: 51
324 attributeDetailsId: 53
327 nextResultSetPosition = 2
330 ZebraExplainInfo zebraExplain_open(
331 Records records, data1_handle dh,
335 ZebraExplainUpdateFunc *updateFunc)
338 ZebraExplainInfo zei;
339 struct zebDatabaseInfoB **zdip;
342 NMEM nmem = nmem_create();
345 yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
347 zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
348 zei->databaseInfo = 0;
349 zei->write_flag = writeFlag;
350 zei->updateHandle = updateHandle;
351 zei->updateFunc = updateFunc;
353 zei->ordinalDatabase = 1;
354 zei->curDatabaseInfo = 0;
355 zei->records = records;
359 data1_get_absyn(zei->dh, "explain", DATA1_XPATH_INDEXING_DISABLE);
363 zei->categoryList = (struct zebraCategoryListInfo *)
364 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
365 zei->categoryList->sysno = 0;
366 zei->categoryList->dirty = 0;
367 zei->categoryList->data1_categoryList = 0;
369 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
372 tm = localtime(&our_time);
373 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
374 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
375 tm->tm_hour, tm->tm_min, tm->tm_sec);
377 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
380 zdip = &zei->databaseInfo;
381 trec = rec_get_root(records); /* get "root" record */
386 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
387 if (trec) /* targetInfo already exists ... */
389 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
391 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
393 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
395 if (!zei->data1_target)
398 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
399 nmem_destroy(zei->nmem);
403 data1_pr_tree(zei->dh, zei->data1_target, stderr);
405 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
409 yaz_log(YLOG_FATAL, "Node node_tgtinfo missing");
410 nmem_destroy(zei->nmem);
413 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
416 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
420 yaz_log(YLOG_FATAL, "Node node_zebra missing");
421 nmem_destroy(zei->nmem);
427 node_list = data1_search_tag(zei->dh, node_zebra->child,
430 np = node_list->child;
432 for(; np; np = np->next)
434 data1_node *node_name = 0;
435 data1_node *node_id = 0;
436 data1_node *node_aid = 0;
438 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
440 for(np2 = np->child; np2; np2 = np2->next)
442 if (np2->which != DATA1N_tag)
444 if (!strcmp(np2->u.tag.tag, "name"))
445 node_name = np2->child;
446 else if (!strcmp(np2->u.tag.tag, "id"))
447 node_id = np2->child;
448 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
449 node_aid = np2->child;
451 assert(node_id && node_name && node_aid);
453 *zdip =(struct zebDatabaseInfoB *)
454 nmem_malloc(zei->nmem, sizeof(**zdip));
455 (*zdip)->readFlag = 1;
457 (*zdip)->data1_database = 0;
458 (*zdip)->recordCount = 0;
459 (*zdip)->recordBytes = 0;
460 zebraExplain_mergeAccessInfo(zei, 0, &(*zdip)->accessInfo);
462 (*zdip)->databaseName = (char *)
463 nmem_malloc(zei->nmem, 1+node_name->u.data.len);
464 memcpy((*zdip)->databaseName, node_name->u.data.data,
465 node_name->u.data.len);
466 (*zdip)->databaseName[node_name->u.data.len] = '\0';
467 (*zdip)->sysno = atoi_zn(node_id->u.data.data,
468 node_id->u.data.len);
469 (*zdip)->attributeDetails = (zebAttributeDetails)
470 nmem_malloc(zei->nmem, sizeof(*(*zdip)->attributeDetails));
471 (*zdip)->attributeDetails->sysno = atoi_zn(node_aid->u.data.data,
472 node_aid->u.data.len);
473 (*zdip)->attributeDetails->readFlag = 1;
474 (*zdip)->attributeDetails->dirty = 0;
475 (*zdip)->attributeDetails->SUInfo = 0;
477 zdip = &(*zdip)->next;
481 np = data1_search_tag(zei->dh, node_zebra->child,
484 assert(np && np->which == DATA1N_data);
485 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
487 np = data1_search_tag(zei->dh, node_zebra->child,
490 assert(np && np->which == DATA1N_data);
491 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
493 np = data1_search_tag(zei->dh, node_zebra->child,
496 assert(np && np->which == DATA1N_data);
497 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
498 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
503 else /* create initial targetInfo */
505 data1_node *node_tgtinfo;
514 data1_read_sgml(zei->dh, zei->nmem,
515 "<explain><targetInfo>TargetInfo\n"
517 "<namedResultSets>1</>\n"
518 "<multipleDBSearch>1</>\n"
519 "<nicknames><name>Zebra</></>\n"
521 if (!zei->data1_target)
523 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
524 nmem_destroy(zei->nmem);
527 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
529 assert(node_tgtinfo);
531 zebraExplain_initCommonInfo(zei, node_tgtinfo);
532 zebraExplain_initAccessInfo(zei, node_tgtinfo);
534 /* write now because we want to be sure about the sysno */
535 trec = rec_new(records);
538 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
539 nmem_destroy(zei->nmem);
542 trec->info[recInfo_fileType] =
543 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
544 trec->info[recInfo_databaseName] =
545 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
547 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
548 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
549 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
550 trec->size[recInfo_storeData] = sgml_len;
552 rec_put(records, &trec);
556 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
558 if (!zei->categoryList->dirty)
560 struct zebraCategoryListInfo *zcl = zei->categoryList;
564 zcl->data1_categoryList =
565 data1_read_sgml(zei->dh, zei->nmem,
566 "<explain><categoryList>CategoryList\n"
569 if (zcl->data1_categoryList)
571 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
574 zebraExplain_initCommonInfo(zei, node_cl);
581 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
582 zebAttributeDetails zad)
585 struct zebSUInfoB **zsuip = &zad->SUInfo;
586 data1_node *node_adinfo, *node_zebra, *node_list, *np;
589 rec = rec_get(zei->records, zad->sysno);
591 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
593 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
594 "/attributeDetails");
595 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
597 node_list = data1_search_tag(zei->dh, node_zebra->child,
599 for (np = node_list->child; np; np = np->next)
601 data1_node *node_str = 0;
602 data1_node *node_ordinal = 0;
603 data1_node *node_type = 0;
604 data1_node *node_cat = 0;
605 data1_node *node_doc_occurrences = 0;
606 data1_node *node_term_occurrences = 0;
609 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
611 for (np2 = np->child; np2; np2 = np2->next)
613 if (np2->which != DATA1N_tag || !np2->child ||
614 np2->child->which != DATA1N_data)
616 if (!strcmp(np2->u.tag.tag, "str"))
617 node_str = np2->child;
618 else if (!strcmp(np2->u.tag.tag, "ordinal"))
619 node_ordinal = np2->child;
620 else if (!strcmp(np2->u.tag.tag, "type"))
621 node_type = np2->child;
622 else if (!strcmp(np2->u.tag.tag, "cat"))
623 node_cat = np2->child;
624 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
625 node_doc_occurrences = np2->child;
626 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
627 node_term_occurrences = np2->child;
630 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
634 assert(node_ordinal);
636 *zsuip = (struct zebSUInfoB *)
637 nmem_malloc(zei->nmem, sizeof(**zsuip));
639 if (node_type && node_type->u.data.len > 0)
640 (*zsuip)->info.index_type =
641 nmem_strdupn(zei->nmem,
642 node_type->u.data.data,
643 node_type->u.data.len);
646 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
647 (*zsuip)->info.index_type = "w";
649 if (node_cat && node_cat->u.data.len > 0)
651 zinfo_index_category_t cat;
653 data1_node *np = node_cat;
654 if (!strncmp(np->u.data.data, "index", np->u.data.len))
655 cat = zinfo_index_category_index;
656 else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
657 cat = zinfo_index_category_sort;
658 else if (!strncmp(np->u.data.data, "alwaysmatches",
660 cat = zinfo_index_category_alwaysmatches;
661 else if (!strncmp(np->u.data.data, "anchor",
663 cat = zinfo_index_category_anchor;
666 yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
667 np->u.data.len, np->u.data.data);
668 cat = zinfo_index_category_index;
670 (*zsuip)->info.cat = cat;
673 (*zsuip)->info.cat = zinfo_index_category_index;
675 if (node_doc_occurrences)
677 data1_node *np = node_doc_occurrences;
678 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
681 if (node_term_occurrences)
683 data1_node *np = node_term_occurrences;
684 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
689 (*zsuip)->info.str = nmem_strdupn(zei->nmem,
690 node_str->u.data.data,
691 node_str->u.data.len);
695 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
698 (*zsuip)->info.ordinal = atoi_n(node_ordinal->u.data.data,
699 node_ordinal->u.data.len);
700 zsuip = &(*zsuip)->next;
707 static void zebraExplain_readDatabase(ZebraExplainInfo zei,
708 struct zebDatabaseInfoB *zdi)
711 data1_node *node_dbinfo, *node_zebra, *np;
714 rec = rec_get(zei->records, zdi->sysno);
716 zdi->data1_database = read_sgml_rec(zei->dh, zei->nmem, rec);
718 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
721 zebraExplain_mergeAccessInfo(zei, node_dbinfo, &zdi->accessInfo);
723 node_zebra = data1_search_tag(zei->dh, node_dbinfo->child,
726 && (np = data1_search_tag(zei->dh, node_zebra->child,
728 && np->child && np->child->which == DATA1N_data)
729 zdi->recordBytes = atoi_zn(np->child->u.data.data,
730 np->child->u.data.len);
733 && (np = data1_search_tag(zei->dh, node_zebra->child,
735 && np->child && np->child->which == DATA1N_data)
736 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
737 np->child->u.data.len);
739 if ((np = data1_search_tag(zei->dh, node_dbinfo->child,
741 (np = data1_search_tag(zei->dh, np->child,
742 "recordCountActual")) &&
743 np->child->which == DATA1N_data)
745 zdi->recordCount = atoi_zn(np->child->u.data.data,
746 np->child->u.data.len);
752 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
754 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
758 if (*zdip == zei->curDatabaseInfo)
760 struct zebDatabaseInfoB *zdi = *zdip;
764 zei->updateHandle = update_handle;
766 if (zdi->attributeDetails)
768 /* remove attribute details keys and delete it */
769 zebAttributeDetails zad = zdi->attributeDetails;
771 rec = rec_get(zei->records, zad->sysno);
772 (*zei->updateFunc)(zei->updateHandle, rec, 0);
775 /* remove database record keys and delete it */
776 rec = rec_get(zei->records, zdi->sysno);
777 (*zei->updateFunc)(zei->updateHandle, rec, 0);
780 /* remove from list */
783 /* current database is IR-Explain-1 */
786 zdip = &(*zdip)->next;
791 int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
793 struct zebDatabaseInfoB *zdi;
794 const char *database_n = strrchr(database, '/');
799 database_n = database;
802 if (zei->curDatabaseInfo &&
803 !STRCASECMP(zei->curDatabaseInfo->databaseName, database))
805 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
807 if (!STRCASECMP(zdi->databaseName, database_n))
813 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
818 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
820 zebraExplain_readDatabase(zei, zdi);
822 if (zdi->attributeDetails->readFlag)
825 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
827 zebraExplain_readAttributeDetails(zei, zdi->attributeDetails);
829 zei->curDatabaseInfo = zdi;
833 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n)
835 data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "commonInfo", 0, n);
836 data1_mk_tag_data_text(zei->dh, c, "dateAdded", zei->date, zei->nmem);
837 data1_mk_tag_data_text(zei->dh, c, "dateChanged", zei->date, zei->nmem);
838 data1_mk_tag_data_text(zei->dh, c, "languageCode", "EN", zei->nmem);
841 static void zebraExplain_updateCommonInfo(ZebraExplainInfo zei, data1_node *n)
843 data1_node *c = data1_search_tag(zei->dh, n->child, "commonInfo");
845 data1_mk_tag_data_text_uni(zei->dh, c, "dateChanged", zei->date,
849 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n)
851 data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "accessInfo", 0, n);
852 data1_node *d = data1_mk_tag(zei->dh, zei->nmem, "unitSystems", 0, c);
853 data1_mk_tag_data_text(zei->dh, d, "string", "ISO", zei->nmem);
856 static void zebraExplain_updateAccessInfo(ZebraExplainInfo zei, data1_node *n,
857 zebAccessInfo accessInfo)
859 data1_node *c = data1_search_tag(zei->dh, n->child, "accessInfo");
865 data1_pr_tree(zei->dh, n, stdout);
866 zebra_exit("zebraExplain_updateAccessInfo");
869 if ((p = accessInfo->attributeSetIds))
871 d = data1_mk_tag_uni(zei->dh, zei->nmem, "attributeSetIds", c);
872 for (; p; p = p->next)
873 data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
875 if ((p = accessInfo->schemas))
877 d = data1_mk_tag_uni(zei->dh, zei->nmem, "schemas", c);
878 for (; p; p = p->next)
879 data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
883 int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database,
884 int explain_database)
886 struct zebDatabaseInfoB *zdi;
887 data1_node *node_dbinfo, *node_adinfo;
888 const char *database_n = strrchr(database, '/');
893 database_n = database;
896 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
899 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
901 if (!STRCASECMP(zdi->databaseName, database_n))
906 /* it's new really. make it */
907 zdi = (struct zebDatabaseInfoB *) nmem_malloc(zei->nmem, sizeof(*zdi));
908 zdi->next = zei->databaseInfo;
909 zei->databaseInfo = zdi;
911 zdi->recordCount = 0;
912 zdi->recordBytes = 0;
914 zdi->databaseName = nmem_strdup(zei->nmem, database_n);
916 zdi->ordinalDatabase = zei->ordinalDatabase++;
918 zebraExplain_mergeAccessInfo(zei, 0, &zdi->accessInfo);
923 zdi->data1_database =
924 data1_read_sgml(zei->dh, zei->nmem,
925 "<explain><databaseInfo>DatabaseInfo\n"
927 if (!zdi->data1_database)
930 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
934 zebraExplain_initCommonInfo(zei, node_dbinfo);
935 zebraExplain_initAccessInfo(zei, node_dbinfo);
937 data1_mk_tag_data_text(zei->dh, node_dbinfo, "name",
938 database, zei->nmem);
940 if (explain_database)
941 data1_mk_tag_data_text(zei->dh, node_dbinfo, "explainDatabase",
944 data1_mk_tag_data_text(zei->dh, node_dbinfo, "userFee",
947 data1_mk_tag_data_text(zei->dh, node_dbinfo, "available",
951 data1_pr_tree(zei->dh, zdi->data1_database, stderr);
955 zei->curDatabaseInfo = zdi;
957 zdi->attributeDetails = (zebAttributeDetails)
958 nmem_malloc(zei->nmem, sizeof(*zdi->attributeDetails));
959 zdi->attributeDetails->readFlag = 0;
960 zdi->attributeDetails->sysno = 0;
961 zdi->attributeDetails->dirty = 1;
962 zdi->attributeDetails->SUInfo = 0;
963 zdi->attributeDetails->data1_tree =
964 data1_read_sgml(zei->dh, zei->nmem,
965 "<explain><attributeDetails>AttributeDetails\n"
968 node_adinfo = data1_search_tag(zei->dh, zdi->attributeDetails->data1_tree,
969 "/attributeDetails");
972 zebraExplain_initCommonInfo(zei, node_adinfo);
974 data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
980 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
981 struct zebraCategoryListInfo *zcl,
988 data1_node *node_ci, *node_categoryList;
990 static char *category[] = {
1002 node_categoryList = zcl->data1_categoryList;
1005 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
1008 drec = createRecord(zei->records, &sysno);
1012 node_ci = data1_search_tag(zei->dh, node_categoryList,
1015 node_ci = data1_mk_tag(zei->dh, zei->nmem, "categories", 0 /* attr */,
1019 for (i = 0; category[i]; i++)
1021 data1_node *node_cat = data1_mk_tag(zei->dh, zei->nmem, "category",
1022 0 /* attr */, node_ci);
1024 data1_mk_tag_data_text(zei->dh, node_cat, "name",
1025 category[i], zei->nmem);
1027 /* extract *searchable* keys from it. We do this here, because
1028 record count, etc. is affected */
1030 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1032 /* convert to "SGML" and write it */
1034 data1_pr_tree(zei->dh, node_categoryList, stderr);
1036 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1037 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1038 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1039 drec->size[recInfo_storeData] = sgml_len;
1041 rec_put(zei->records, &drec);
1044 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
1045 zebAttributeDetails zad,
1046 const char *databaseName,
1052 data1_node *node_adinfo, *node_list, *node_zebra;
1053 struct zebSUInfoB *zsui;
1060 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1061 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1064 drec = createRecord(zei->records, &zad->sysno);
1067 assert(zad->data1_tree);
1069 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
1070 "/attributeDetails");
1071 zebraExplain_updateCommonInfo(zei, node_adinfo);
1073 /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
1074 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1075 "zebraInfo", node_adinfo);
1077 /* extract *searchable* keys from it. We do this here, because
1078 record count, etc. is affected */
1080 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1081 node_list = data1_mk_tag_uni(zei->dh, zei->nmem,
1082 "attrlist", node_zebra);
1083 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1085 data1_node *node_attr;
1086 node_attr = data1_mk_tag(zei->dh, zei->nmem, "attr", 0 /* attr */,
1089 data1_mk_tag_data_text(zei->dh, node_attr, "type",
1090 zsui->info.index_type, zei->nmem);
1091 data1_mk_tag_data_text(zei->dh, node_attr, "str",
1092 zsui->info.str, zei->nmem);
1093 data1_mk_tag_data_int(zei->dh, node_attr, "ordinal",
1094 zsui->info.ordinal, zei->nmem);
1096 data1_mk_tag_data_zint(zei->dh, node_attr, "dococcurrences",
1097 zsui->info.doc_occurrences, zei->nmem);
1098 data1_mk_tag_data_zint(zei->dh, node_attr, "termoccurrences",
1099 zsui->info.term_occurrences, zei->nmem);
1100 switch(zsui->info.cat)
1102 case zinfo_index_category_index:
1103 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1104 "index", zei->nmem); break;
1105 case zinfo_index_category_sort:
1106 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1107 "sort", zei->nmem); break;
1108 case zinfo_index_category_alwaysmatches:
1109 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1110 "alwaysmatches", zei->nmem); break;
1111 case zinfo_index_category_anchor:
1112 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1113 "anchor", zei->nmem); break;
1116 /* convert to "SGML" and write it */
1118 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1120 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1122 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1123 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1124 drec->size[recInfo_storeData] = sgml_len;
1126 rec_put(zei->records, &drec);
1129 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
1130 struct zebDatabaseInfoB *zdi,
1136 data1_node *node_dbinfo, *node_count, *node_zebra;
1143 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1145 drec = createRecord(zei->records, &zdi->sysno);
1148 assert(zdi->data1_database);
1150 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
1153 assert(node_dbinfo);
1154 zebraExplain_updateCommonInfo(zei, node_dbinfo);
1155 zebraExplain_updateAccessInfo(zei, node_dbinfo, zdi->accessInfo);
1158 node_count = data1_mk_tag_uni(zei->dh, zei->nmem,
1159 "recordCount", node_dbinfo);
1160 data1_mk_tag_data_zint(zei->dh, node_count, "recordCountActual",
1161 zdi->recordCount, zei->nmem);
1163 /* zebra info (private) */
1164 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1165 "zebraInfo", node_dbinfo);
1167 /* extract *searchable* keys from it. We do this here, because
1168 record count, etc. is affected */
1170 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1171 data1_mk_tag_data_zint(zei->dh, node_zebra,
1172 "recordBytes", zdi->recordBytes, zei->nmem);
1174 data1_mk_tag_data_zint(zei->dh, node_zebra,
1175 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1177 /* convert to "SGML" and write it */
1179 data1_pr_tree(zei->dh, zdi->data1_database, stderr);
1181 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1183 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1184 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1185 drec->size[recInfo_storeData] = sgml_len;
1187 rec_put(zei->records, &drec);
1190 static void writeAttributeValues(ZebraExplainInfo zei,
1191 data1_node *node_values,
1192 data1_attset *attset)
1195 data1_attset_child *c;
1200 for (c = attset->children; c; c = c->next)
1201 writeAttributeValues(zei, node_values, c->child);
1202 for (atts = attset->atts; atts; atts = atts->next)
1204 data1_node *node_value;
1206 node_value = data1_mk_tag(zei->dh, zei->nmem, "attributeValue",
1207 0 /* attr */, node_values);
1208 data1_mk_tag_data_text(zei->dh, node_value, "name",
1209 atts->name, zei->nmem);
1210 node_value = data1_mk_tag(zei->dh, zei->nmem, "value",
1211 0 /* attr */, node_value);
1212 data1_mk_tag_data_int(zei->dh, node_value, "numeric",
1213 atts->value, zei->nmem);
1218 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
1225 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1226 data1_node *node_values;
1227 struct data1_attset *attset = 0;
1230 attset = data1_attset_search_id(zei->dh, o->oid);
1233 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1234 attset ? attset->name : "<unknown>");
1237 drec = createRecord(zei->records, &o->sysno);
1241 data1_read_sgml(zei->dh, zei->nmem,
1242 "<explain><attributeSetInfo>AttributeSetInfo\n"
1245 node_attinfo = data1_search_tag(zei->dh, node_root,
1246 "/attributeSetInfo");
1248 assert(node_attinfo);
1249 zebraExplain_initCommonInfo(zei, node_attinfo);
1250 zebraExplain_updateCommonInfo(zei, node_attinfo);
1252 data1_mk_tag_data_oid(zei->dh, node_attinfo,
1253 "oid", o->oid, zei->nmem);
1254 if (attset && attset->name)
1255 data1_mk_tag_data_text(zei->dh, node_attinfo,
1256 "name", attset->name, zei->nmem);
1258 node_attributes = data1_mk_tag_uni(zei->dh, zei->nmem,
1259 "attributes", node_attinfo);
1260 node_atttype = data1_mk_tag_uni(zei->dh, zei->nmem,
1261 "attributeType", node_attributes);
1262 data1_mk_tag_data_text(zei->dh, node_atttype,
1263 "name", "Use", zei->nmem);
1264 data1_mk_tag_data_text(zei->dh, node_atttype,
1265 "description", "Use Attribute", zei->nmem);
1266 data1_mk_tag_data_int(zei->dh, node_atttype,
1267 "type", 1, zei->nmem);
1268 node_values = data1_mk_tag(zei->dh, zei->nmem,
1269 "attributeValues", 0 /* attr */, node_atttype);
1271 writeAttributeValues(zei, node_values, attset);
1273 /* extract *searchable* keys from it. We do this here, because
1274 record count, etc. is affected */
1276 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1277 /* convert to "SGML" and write it */
1279 data1_pr_tree(zei->dh, node_root, stderr);
1281 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1282 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1283 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1284 drec->size[recInfo_storeData] = sgml_len;
1286 rec_put(zei->records, &drec);
1289 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush)
1291 struct zebDatabaseInfoB *zdi;
1292 data1_node *node_tgtinfo, *node_list, *node_zebra;
1301 trec = rec_get_root(zei->records);
1302 xfree(trec->info[recInfo_storeData]);
1304 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
1306 assert(node_tgtinfo);
1308 zebraExplain_updateCommonInfo(zei, node_tgtinfo);
1309 zebraExplain_updateAccessInfo(zei, node_tgtinfo, zei->accessInfo);
1311 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1312 "zebraInfo", node_tgtinfo);
1313 /* convert to "SGML" and write it */
1315 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1317 data1_mk_tag_data_text(zei->dh, node_zebra, "version",
1318 ZEBRAVER, zei->nmem);
1319 node_list = data1_mk_tag(zei->dh, zei->nmem,
1320 "databaseList", 0 /* attr */, node_zebra);
1321 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1323 data1_node *node_db;
1324 node_db = data1_mk_tag(zei->dh, zei->nmem,
1325 "database", 0 /* attr */, node_list);
1326 data1_mk_tag_data_text(zei->dh, node_db, "name",
1327 zdi->databaseName, zei->nmem);
1328 data1_mk_tag_data_zint(zei->dh, node_db, "id",
1329 zdi->sysno, zei->nmem);
1330 data1_mk_tag_data_zint(zei->dh, node_db, "attributeDetailsId",
1331 zdi->attributeDetails->sysno, zei->nmem);
1333 data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalSU",
1334 zei->ordinalSU, zei->nmem);
1336 data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalDatabase",
1337 zei->ordinalDatabase, zei->nmem);
1339 data1_mk_tag_data_zint(zei->dh, node_zebra, "runNumber",
1340 zei->runNumber, zei->nmem);
1343 data1_pr_tree(zei->dh, zei->data1_target, stderr);
1345 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1347 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1348 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
1349 trec->size[recInfo_storeData] = sgml_len;
1351 rec_put(zei->records, &trec);
1354 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
1355 zinfo_index_category_t cat,
1356 const char *index_type,
1359 struct zebSUInfoB **zsui;
1361 assert(zei->curDatabaseInfo);
1362 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1363 *zsui; zsui = &(*zsui)->next)
1364 if ( (index_type == 0
1365 || !strcmp((*zsui)->info.index_type, index_type))
1366 && (*zsui)->info.cat == cat
1367 && !yaz_matchstr((*zsui)->info.str, str))
1369 struct zebSUInfoB *zsui_this = *zsui;
1371 /* take it out of the list and move to front */
1372 *zsui = (*zsui)->next;
1373 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1374 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1376 return zsui_this->info.ordinal;
1381 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1382 int (*f)(void *handle, int ord))
1384 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1387 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1388 for ( ;zsui; zsui = zsui->next)
1389 (*f)(handle, zsui->info.ordinal);
1395 struct zebSUInfoB *zebraExplain_get_sui_info(ZebraExplainInfo zei, int ord,
1399 struct zebDatabaseInfoB *zdb;
1401 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1403 struct zebSUInfoB **zsui;
1405 if (zdb->attributeDetails->readFlag)
1406 zebraExplain_readAttributeDetails(zei, zdb->attributeDetails);
1408 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1409 zsui = &(*zsui)->next)
1410 if ((*zsui)->info.ordinal == ord)
1412 struct zebSUInfoB *zsui_this = *zsui;
1414 /* take it out of the list and move to front */
1415 *zsui = (*zsui)->next;
1416 zsui_this->next = zdb->attributeDetails->SUInfo;
1417 zdb->attributeDetails->SUInfo = zsui_this;
1420 zdb->attributeDetails->dirty = 1;
1422 *db = zdb->databaseName;
1431 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1432 int term_delta, int doc_delta)
1434 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1437 zsui->info.term_occurrences += term_delta;
1438 zsui->info.doc_occurrences += doc_delta;
1444 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1445 zint *term_occurrences,
1446 zint *doc_occurrences)
1448 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1451 *term_occurrences = zsui->info.term_occurrences;
1452 *doc_occurrences = zsui->info.doc_occurrences;
1458 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1460 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1462 return zsui->info.doc_occurrences;
1466 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1468 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1470 return zsui->info.term_occurrences;
1474 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1475 const char **index_type,
1477 const char **string_index)
1479 struct zebSUInfoB *zsui;
1486 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1490 *string_index = zsui->info.str;
1492 *index_type = zsui->info.index_type;
1500 zebAccessObject zebraExplain_announceOid(ZebraExplainInfo zei,
1501 zebAccessObject *op,
1506 for (ao = *op; ao; ao = ao->next)
1507 if (!oid_oidcmp(oid, ao->oid))
1511 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
1514 ao->oid = odr_oiddup_nmem(zei->nmem, oid);
1521 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1522 zinfo_index_category_t cat,
1523 const char *index_type)
1525 struct zebSUInfoB *zsui;
1527 assert(zei->curDatabaseInfo);
1528 zsui = (struct zebSUInfoB *) nmem_malloc(zei->nmem, sizeof(*zsui));
1529 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1530 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1531 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1533 zsui->info.index_type = nmem_strdup(zei->nmem, index_type);
1534 zsui->info.cat = cat;
1535 zsui->info.doc_occurrences = 0;
1536 zsui->info.term_occurrences = 0;
1537 zsui->info.ordinal = (zei->ordinalSU)++;
1541 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1542 zinfo_index_category_t cat,
1543 const char *index_type,
1544 const char *index_name)
1546 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1548 zsui->info.str = nmem_strdup(zei->nmem, index_name);
1549 return zsui->info.ordinal;
1552 void zebraExplain_addSchema(ZebraExplainInfo zei, Odr_oid *oid)
1554 zebraExplain_announceOid(zei, &zei->accessInfo->schemas, oid);
1555 zebraExplain_announceOid(zei, &zei->curDatabaseInfo->
1556 accessInfo->schemas, oid);
1559 void zebraExplain_recordBytesIncrement(ZebraExplainInfo zei, int adjust_num)
1561 assert(zei->curDatabaseInfo);
1565 zei->curDatabaseInfo->recordBytes += adjust_num;
1566 zei->curDatabaseInfo->dirty = 1;
1570 void zebraExplain_recordCountIncrement(ZebraExplainInfo zei, int adjust_num)
1572 assert(zei->curDatabaseInfo);
1576 zei->curDatabaseInfo->recordCount += adjust_num;
1577 zei->curDatabaseInfo->dirty = 1;
1581 zint zebraExplain_runNumberIncrement(ZebraExplainInfo zei, int adjust_num)
1587 return zei->runNumber += adjust_num;
1590 RecordAttr *rec_init_attr(ZebraExplainInfo zei, Record rec)
1592 RecordAttr *recordAttr;
1594 if (rec->info[recInfo_attr])
1595 return (RecordAttr *) rec->info[recInfo_attr];
1596 recordAttr = (RecordAttr *) xmalloc(sizeof(*recordAttr));
1598 memset(recordAttr, '\0', sizeof(*recordAttr));
1599 rec->info[recInfo_attr] = (char *) recordAttr;
1600 rec->size[recInfo_attr] = sizeof(*recordAttr);
1602 recordAttr->recordSize = 0;
1603 recordAttr->recordOffset = 0;
1604 recordAttr->runNumber = zei->runNumber;
1605 recordAttr->staticrank = 0;
1609 static void att_loadset(void *p, const char *n, const char *name)
1611 data1_handle dh = (data1_handle) p;
1612 if (!data1_get_attset(dh, name))
1613 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1616 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1618 if (!zei->curDatabaseInfo)
1620 return zei->curDatabaseInfo->ordinalDatabase;
1623 void zebraExplain_loadAttsets(data1_handle dh, Res res)
1625 res_trav(res, "attset", dh, att_loadset);
1629 zebraExplain_addSU adds to AttributeDetails for a database and
1630 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1631 exist for the database.
1633 If the database doesn't exist globally (in TargetInfo) an
1634 AttributeSetInfo must be added (globally).
1639 * indent-tabs-mode: nil
1641 * vim: shiftwidth=4 tabstop=8 expandtab