1 /* This file is part of the Zebra server.
2 Copyright (C) Index Data
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 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);
773 rec_del(zei->records, &rec);
775 /* remove database record keys and delete it */
776 rec = rec_get(zei->records, zdi->sysno);
777 (*zei->updateFunc)(zei->updateHandle, rec, 0);
778 rec_del(zei->records, &rec);
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,
1383 const char *index_type,
1384 const char *string_index,
1385 zinfo_index_category_t cat))
1387 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1390 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1391 for ( ;zsui; zsui = zsui->next)
1392 (*f)(handle, zsui->info.ordinal,
1393 zsui->info.index_type, zsui->info.str,
1400 struct zebSUInfoB *zebraExplain_get_sui_info(ZebraExplainInfo zei, int ord,
1404 struct zebDatabaseInfoB *zdb;
1406 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1408 struct zebSUInfoB **zsui;
1410 if (zdb->attributeDetails->readFlag)
1411 zebraExplain_readAttributeDetails(zei, zdb->attributeDetails);
1413 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1414 zsui = &(*zsui)->next)
1415 if ((*zsui)->info.ordinal == ord)
1417 struct zebSUInfoB *zsui_this = *zsui;
1419 /* take it out of the list and move to front */
1420 *zsui = (*zsui)->next;
1421 zsui_this->next = zdb->attributeDetails->SUInfo;
1422 zdb->attributeDetails->SUInfo = zsui_this;
1425 zdb->attributeDetails->dirty = 1;
1427 *db = zdb->databaseName;
1436 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1437 int term_delta, int doc_delta)
1439 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1442 zsui->info.term_occurrences += term_delta;
1443 zsui->info.doc_occurrences += doc_delta;
1449 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1450 zint *term_occurrences,
1451 zint *doc_occurrences)
1453 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1456 *term_occurrences = zsui->info.term_occurrences;
1457 *doc_occurrences = zsui->info.doc_occurrences;
1463 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1465 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1467 return zsui->info.doc_occurrences;
1471 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1473 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1475 return zsui->info.term_occurrences;
1479 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1480 const char **index_type,
1482 const char **string_index)
1484 struct zebSUInfoB *zsui;
1491 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1495 *string_index = zsui->info.str;
1497 *index_type = zsui->info.index_type;
1505 zebAccessObject zebraExplain_announceOid(ZebraExplainInfo zei,
1506 zebAccessObject *op,
1511 for (ao = *op; ao; ao = ao->next)
1512 if (!oid_oidcmp(oid, ao->oid))
1516 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
1519 ao->oid = odr_oiddup_nmem(zei->nmem, oid);
1526 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1527 zinfo_index_category_t cat,
1528 const char *index_type)
1530 struct zebSUInfoB *zsui;
1532 assert(zei->curDatabaseInfo);
1533 zsui = (struct zebSUInfoB *) nmem_malloc(zei->nmem, sizeof(*zsui));
1534 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1535 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1536 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1538 zsui->info.index_type = nmem_strdup(zei->nmem, index_type);
1539 zsui->info.cat = cat;
1540 zsui->info.doc_occurrences = 0;
1541 zsui->info.term_occurrences = 0;
1542 zsui->info.ordinal = (zei->ordinalSU)++;
1546 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1547 zinfo_index_category_t cat,
1548 const char *index_type,
1549 const char *index_name)
1551 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1553 zsui->info.str = nmem_strdup(zei->nmem, index_name);
1554 return zsui->info.ordinal;
1557 void zebraExplain_addSchema(ZebraExplainInfo zei, Odr_oid *oid)
1559 zebraExplain_announceOid(zei, &zei->accessInfo->schemas, oid);
1560 zebraExplain_announceOid(zei, &zei->curDatabaseInfo->
1561 accessInfo->schemas, oid);
1564 void zebraExplain_recordBytesIncrement(ZebraExplainInfo zei, int adjust_num)
1566 assert(zei->curDatabaseInfo);
1570 zei->curDatabaseInfo->recordBytes += adjust_num;
1571 zei->curDatabaseInfo->dirty = 1;
1575 void zebraExplain_recordCountIncrement(ZebraExplainInfo zei, int adjust_num)
1577 assert(zei->curDatabaseInfo);
1581 zei->curDatabaseInfo->recordCount += adjust_num;
1582 zei->curDatabaseInfo->dirty = 1;
1586 zint zebraExplain_runNumberIncrement(ZebraExplainInfo zei, int adjust_num)
1592 return zei->runNumber += adjust_num;
1595 RecordAttr *rec_init_attr(ZebraExplainInfo zei, Record rec)
1597 RecordAttr *recordAttr;
1599 if (rec->info[recInfo_attr])
1600 return (RecordAttr *) rec->info[recInfo_attr];
1601 recordAttr = (RecordAttr *) xmalloc(sizeof(*recordAttr));
1603 memset(recordAttr, '\0', sizeof(*recordAttr));
1604 rec->info[recInfo_attr] = (char *) recordAttr;
1605 rec->size[recInfo_attr] = sizeof(*recordAttr);
1607 recordAttr->recordSize = 0;
1608 recordAttr->recordOffset = 0;
1609 recordAttr->runNumber = zei->runNumber;
1610 recordAttr->staticrank = 0;
1614 static void att_loadset(void *p, const char *n, const char *name)
1616 data1_handle dh = (data1_handle) p;
1617 if (!data1_get_attset(dh, name))
1618 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1621 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1623 if (!zei->curDatabaseInfo)
1625 return zei->curDatabaseInfo->ordinalDatabase;
1628 void zebraExplain_loadAttsets(data1_handle dh, Res res)
1630 res_trav(res, "attset", dh, att_loadset);
1634 zebraExplain_addSU adds to AttributeDetails for a database and
1635 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1636 exist for the database.
1638 If the database doesn't exist globally (in TargetInfo) an
1639 AttributeSetInfo must be added (globally).
1644 * c-file-style: "Stroustrup"
1645 * indent-tabs-mode: nil
1647 * vim: shiftwidth=4 tabstop=8 expandtab