1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2011 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
20 #include <sys/types.h>
26 #include <idzebra/version.h>
33 zinfo_index_category_t cat;
37 zint term_occurrences;
41 struct zebSUInfo info;
42 struct zebSUInfoB *next;
45 typedef struct zebAccessObjectB *zebAccessObject;
46 struct zebAccessObjectB {
53 typedef struct zebAccessInfoB *zebAccessInfo;
54 struct zebAccessInfoB {
55 zebAccessObject attributeSetIds;
56 zebAccessObject schemas;
60 struct zebSUInfoB *SUInfo;
64 data1_node *data1_tree;
65 } *zebAttributeDetails;
67 struct zebDatabaseInfoB {
68 zebAttributeDetails attributeDetails;
71 data1_node *data1_database;
72 zint recordCount; /* records in db */
73 zint recordBytes; /* size of records */
74 zint sysno; /* sysno of database info */
75 int readFlag; /* 1: read is needed when referenced; 0 if not */
76 int dirty; /* 1: database is dirty: write is needed */
77 struct zebDatabaseInfoB *next;
78 zebAccessInfo accessInfo;
81 struct zebraExplainAttset {
84 struct zebraExplainAttset *next;
87 struct zebraCategoryListInfo {
90 data1_node *data1_categoryList;
93 struct zebraExplainInfo {
102 struct zebraExplainAttset *attsets;
104 data1_node *data1_target;
105 struct zebraCategoryListInfo *categoryList;
106 struct zebDatabaseInfoB *databaseInfo;
107 struct zebDatabaseInfoB *curDatabaseInfo;
108 zebAccessInfo accessInfo;
109 char date[15]; /* YYYY MMDD HH MM SS */
110 ZebraExplainUpdateFunc *updateFunc;
114 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
115 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
117 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
119 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
122 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
123 struct zebDatabaseInfoB *zdi,
125 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
126 zebAttributeDetails zad,
127 const char *databaseName,
129 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
130 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
133 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
134 struct zebraCategoryListInfo *zcl,
138 static Record createRecord(Records records, zint *sysno)
143 rec = rec_get(records, *sysno);
146 xfree(rec->info[recInfo_storeData]);
150 rec = rec_new(records);
155 rec->info[recInfo_fileType] =
156 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
157 rec->info[recInfo_databaseName] =
158 rec_strdup("IR-Explain-1",
159 &rec->size[recInfo_databaseName]);
164 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
168 zei->updateHandle = handle;
171 struct zebDatabaseInfoB *zdi;
174 /* write each database info record */
175 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
177 zebraExplain_writeDatabase(zei, zdi, 1);
178 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
179 zdi->databaseName, 1);
181 zebraExplain_writeTarget(zei, 1);
182 zebraExplain_writeCategoryList(zei,
185 assert(zei->accessInfo);
186 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
188 zebraExplain_writeAttributeSet(zei, o, 1);
189 for (o = zei->accessInfo->schemas; o; o = o->next)
192 /* zebraExplain_writeSchema(zei, o, 1); */
195 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
197 zebraExplain_writeDatabase(zei, zdi, 0);
198 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
199 zdi->databaseName, 0);
201 zebraExplain_writeTarget(zei, 0);
205 void zebraExplain_close(ZebraExplainInfo zei)
208 yaz_log(YLOG_LOG, "zebraExplain_close");
212 zebraExplain_flush(zei, zei->updateHandle);
213 nmem_destroy(zei->nmem);
216 void zebraExplain_mergeOids(ZebraExplainInfo zei, data1_node *n,
221 for (np = n->child; np; np = np->next)
228 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
230 len = np->child->u.data.len;
233 memcpy(str, np->child->u.data.data, len);
236 oid = odr_getoidbystr_nmem(zei->nmem, str);
238 for (ao = *op; ao; ao = ao->next)
239 if (!oid_oidcmp(oid, ao->oid))
246 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
256 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
257 zebAccessInfo *accessInfo)
263 *accessInfo = (zebAccessInfo)
264 nmem_malloc(zei->nmem, sizeof(**accessInfo));
265 (*accessInfo)->attributeSetIds = 0;
266 (*accessInfo)->schemas = 0;
270 if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
272 if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
273 zebraExplain_mergeOids(zei, np,
274 &(*accessInfo)->attributeSetIds);
275 if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
276 zebraExplain_mergeOids(zei, np,
277 &(*accessInfo)->schemas);
286 databaseList (list of databases)
291 targetInfo: TargetInfo
298 dateAdded: 20030630190601
299 dateChanged: 20030630190601
305 oid: 1.2.840.10003.3.2
306 oid: 1.2.840.10003.3.5
307 oid: 1.2.840.10003.3.1
309 oid: 1.2.840.10003.13.1000.81.2
310 oid: 1.2.840.10003.13.2
317 attributeDetailsId: 51
321 attributeDetailsId: 53
324 nextResultSetPosition = 2
327 ZebraExplainInfo zebraExplain_open(
328 Records records, data1_handle dh,
332 ZebraExplainUpdateFunc *updateFunc)
335 ZebraExplainInfo zei;
336 struct zebDatabaseInfoB **zdip;
339 NMEM nmem = nmem_create();
342 yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
344 zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
345 zei->databaseInfo = 0;
346 zei->write_flag = writeFlag;
347 zei->updateHandle = updateHandle;
348 zei->updateFunc = updateFunc;
350 zei->ordinalDatabase = 1;
351 zei->curDatabaseInfo = 0;
352 zei->records = records;
356 data1_get_absyn(zei->dh, "explain", DATA1_XPATH_INDEXING_DISABLE);
360 zei->categoryList = (struct zebraCategoryListInfo *)
361 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
362 zei->categoryList->sysno = 0;
363 zei->categoryList->dirty = 0;
364 zei->categoryList->data1_categoryList = 0;
366 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
369 tm = localtime(&our_time);
370 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
371 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
372 tm->tm_hour, tm->tm_min, tm->tm_sec);
374 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
377 zdip = &zei->databaseInfo;
378 trec = rec_get_root(records); /* get "root" record */
383 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
384 if (trec) /* targetInfo already exists ... */
386 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
388 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
390 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
392 if (!zei->data1_target)
395 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
396 nmem_destroy(zei->nmem);
400 data1_pr_tree(zei->dh, zei->data1_target, stderr);
402 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
406 yaz_log(YLOG_FATAL, "Node node_tgtinfo missing");
407 nmem_destroy(zei->nmem);
410 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
413 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
417 yaz_log(YLOG_FATAL, "Node node_zebra missing");
418 nmem_destroy(zei->nmem);
424 node_list = data1_search_tag(zei->dh, node_zebra->child,
427 np = node_list->child;
429 for(; np; np = np->next)
431 data1_node *node_name = 0;
432 data1_node *node_id = 0;
433 data1_node *node_aid = 0;
435 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
437 for(np2 = np->child; np2; np2 = np2->next)
439 if (np2->which != DATA1N_tag)
441 if (!strcmp(np2->u.tag.tag, "name"))
442 node_name = np2->child;
443 else if (!strcmp(np2->u.tag.tag, "id"))
444 node_id = np2->child;
445 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
446 node_aid = np2->child;
448 assert(node_id && node_name && node_aid);
450 *zdip =(struct zebDatabaseInfoB *)
451 nmem_malloc(zei->nmem, sizeof(**zdip));
452 (*zdip)->readFlag = 1;
454 (*zdip)->data1_database = 0;
455 (*zdip)->recordCount = 0;
456 (*zdip)->recordBytes = 0;
457 zebraExplain_mergeAccessInfo(zei, 0, &(*zdip)->accessInfo);
459 (*zdip)->databaseName = (char *)
460 nmem_malloc(zei->nmem, 1+node_name->u.data.len);
461 memcpy((*zdip)->databaseName, node_name->u.data.data,
462 node_name->u.data.len);
463 (*zdip)->databaseName[node_name->u.data.len] = '\0';
464 (*zdip)->sysno = atoi_zn(node_id->u.data.data,
465 node_id->u.data.len);
466 (*zdip)->attributeDetails = (zebAttributeDetails)
467 nmem_malloc(zei->nmem, sizeof(*(*zdip)->attributeDetails));
468 (*zdip)->attributeDetails->sysno = atoi_zn(node_aid->u.data.data,
469 node_aid->u.data.len);
470 (*zdip)->attributeDetails->readFlag = 1;
471 (*zdip)->attributeDetails->dirty = 0;
472 (*zdip)->attributeDetails->SUInfo = 0;
474 zdip = &(*zdip)->next;
478 np = data1_search_tag(zei->dh, node_zebra->child,
481 assert(np && np->which == DATA1N_data);
482 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
484 np = data1_search_tag(zei->dh, node_zebra->child,
487 assert(np && np->which == DATA1N_data);
488 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
490 np = data1_search_tag(zei->dh, node_zebra->child,
493 assert(np && np->which == DATA1N_data);
494 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
495 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
500 else /* create initial targetInfo */
502 data1_node *node_tgtinfo;
511 data1_read_sgml(zei->dh, zei->nmem,
512 "<explain><targetInfo>TargetInfo\n"
514 "<namedResultSets>1</>\n"
515 "<multipleDBSearch>1</>\n"
516 "<nicknames><name>Zebra</></>\n"
518 if (!zei->data1_target)
520 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
521 nmem_destroy(zei->nmem);
524 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
526 assert(node_tgtinfo);
528 zebraExplain_initCommonInfo(zei, node_tgtinfo);
529 zebraExplain_initAccessInfo(zei, node_tgtinfo);
531 /* write now because we want to be sure about the sysno */
532 trec = rec_new(records);
535 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
536 nmem_destroy(zei->nmem);
539 trec->info[recInfo_fileType] =
540 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
541 trec->info[recInfo_databaseName] =
542 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
544 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
545 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
546 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
547 trec->size[recInfo_storeData] = sgml_len;
549 rec_put(records, &trec);
553 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
555 if (!zei->categoryList->dirty)
557 struct zebraCategoryListInfo *zcl = zei->categoryList;
561 zcl->data1_categoryList =
562 data1_read_sgml(zei->dh, zei->nmem,
563 "<explain><categoryList>CategoryList\n"
566 if (zcl->data1_categoryList)
568 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
571 zebraExplain_initCommonInfo(zei, node_cl);
578 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
579 zebAttributeDetails zad)
582 struct zebSUInfoB **zsuip = &zad->SUInfo;
583 data1_node *node_adinfo, *node_zebra, *node_list, *np;
586 rec = rec_get(zei->records, zad->sysno);
588 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
590 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
591 "/attributeDetails");
592 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
594 node_list = data1_search_tag(zei->dh, node_zebra->child,
596 for (np = node_list->child; np; np = np->next)
598 data1_node *node_str = 0;
599 data1_node *node_ordinal = 0;
600 data1_node *node_type = 0;
601 data1_node *node_cat = 0;
602 data1_node *node_doc_occurrences = 0;
603 data1_node *node_term_occurrences = 0;
606 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
608 for (np2 = np->child; np2; np2 = np2->next)
610 if (np2->which != DATA1N_tag || !np2->child ||
611 np2->child->which != DATA1N_data)
613 if (!strcmp(np2->u.tag.tag, "str"))
614 node_str = np2->child;
615 else if (!strcmp(np2->u.tag.tag, "ordinal"))
616 node_ordinal = np2->child;
617 else if (!strcmp(np2->u.tag.tag, "type"))
618 node_type = np2->child;
619 else if (!strcmp(np2->u.tag.tag, "cat"))
620 node_cat = np2->child;
621 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
622 node_doc_occurrences = np2->child;
623 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
624 node_term_occurrences = np2->child;
627 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
631 assert(node_ordinal);
633 *zsuip = (struct zebSUInfoB *)
634 nmem_malloc(zei->nmem, sizeof(**zsuip));
636 if (node_type && node_type->u.data.len > 0)
637 (*zsuip)->info.index_type =
638 nmem_strdupn(zei->nmem,
639 node_type->u.data.data,
640 node_type->u.data.len);
643 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
644 (*zsuip)->info.index_type = "w";
646 if (node_cat && node_cat->u.data.len > 0)
648 zinfo_index_category_t cat;
650 data1_node *np = node_cat;
651 if (!strncmp(np->u.data.data, "index", np->u.data.len))
652 cat = zinfo_index_category_index;
653 else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
654 cat = zinfo_index_category_sort;
655 else if (!strncmp(np->u.data.data, "alwaysmatches",
657 cat = zinfo_index_category_alwaysmatches;
658 else if (!strncmp(np->u.data.data, "anchor",
660 cat = zinfo_index_category_anchor;
663 yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
664 np->u.data.len, np->u.data.data);
665 cat = zinfo_index_category_index;
667 (*zsuip)->info.cat = cat;
670 (*zsuip)->info.cat = zinfo_index_category_index;
672 if (node_doc_occurrences)
674 data1_node *np = node_doc_occurrences;
675 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
678 if (node_term_occurrences)
680 data1_node *np = node_term_occurrences;
681 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
686 (*zsuip)->info.str = nmem_strdupn(zei->nmem,
687 node_str->u.data.data,
688 node_str->u.data.len);
692 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
695 (*zsuip)->info.ordinal = atoi_n(node_ordinal->u.data.data,
696 node_ordinal->u.data.len);
697 zsuip = &(*zsuip)->next;
704 static void zebraExplain_readDatabase(ZebraExplainInfo zei,
705 struct zebDatabaseInfoB *zdi)
708 data1_node *node_dbinfo, *node_zebra, *np;
711 rec = rec_get(zei->records, zdi->sysno);
713 zdi->data1_database = read_sgml_rec(zei->dh, zei->nmem, rec);
715 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
718 zebraExplain_mergeAccessInfo(zei, node_dbinfo, &zdi->accessInfo);
720 node_zebra = data1_search_tag(zei->dh, node_dbinfo->child,
723 && (np = data1_search_tag(zei->dh, node_zebra->child,
725 && np->child && np->child->which == DATA1N_data)
726 zdi->recordBytes = atoi_zn(np->child->u.data.data,
727 np->child->u.data.len);
730 && (np = data1_search_tag(zei->dh, node_zebra->child,
732 && np->child && np->child->which == DATA1N_data)
733 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
734 np->child->u.data.len);
736 if ((np = data1_search_tag(zei->dh, node_dbinfo->child,
738 (np = data1_search_tag(zei->dh, np->child,
739 "recordCountActual")) &&
740 np->child->which == DATA1N_data)
742 zdi->recordCount = atoi_zn(np->child->u.data.data,
743 np->child->u.data.len);
749 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
751 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
755 if (*zdip == zei->curDatabaseInfo)
757 struct zebDatabaseInfoB *zdi = *zdip;
761 zei->updateHandle = update_handle;
763 if (zdi->attributeDetails)
765 /* remove attribute details keys and delete it */
766 zebAttributeDetails zad = zdi->attributeDetails;
768 rec = rec_get(zei->records, zad->sysno);
769 (*zei->updateFunc)(zei->updateHandle, rec, 0);
770 rec_del(zei->records, &rec);
772 /* remove database record keys and delete it */
773 rec = rec_get(zei->records, zdi->sysno);
774 (*zei->updateFunc)(zei->updateHandle, rec, 0);
775 rec_del(zei->records, &rec);
777 /* remove from list */
780 /* current database is IR-Explain-1 */
783 zdip = &(*zdip)->next;
788 int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
790 struct zebDatabaseInfoB *zdi;
791 const char *database_n = strrchr(database, '/');
796 database_n = database;
799 if (zei->curDatabaseInfo &&
800 !STRCASECMP(zei->curDatabaseInfo->databaseName, database))
802 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
804 if (!STRCASECMP(zdi->databaseName, database_n))
810 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
815 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
817 zebraExplain_readDatabase(zei, zdi);
819 if (zdi->attributeDetails->readFlag)
822 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
824 zebraExplain_readAttributeDetails(zei, zdi->attributeDetails);
826 zei->curDatabaseInfo = zdi;
830 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n)
832 data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "commonInfo", 0, n);
833 data1_mk_tag_data_text(zei->dh, c, "dateAdded", zei->date, zei->nmem);
834 data1_mk_tag_data_text(zei->dh, c, "dateChanged", zei->date, zei->nmem);
835 data1_mk_tag_data_text(zei->dh, c, "languageCode", "EN", zei->nmem);
838 static void zebraExplain_updateCommonInfo(ZebraExplainInfo zei, data1_node *n)
840 data1_node *c = data1_search_tag(zei->dh, n->child, "commonInfo");
842 data1_mk_tag_data_text_uni(zei->dh, c, "dateChanged", zei->date,
846 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n)
848 data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "accessInfo", 0, n);
849 data1_node *d = data1_mk_tag(zei->dh, zei->nmem, "unitSystems", 0, c);
850 data1_mk_tag_data_text(zei->dh, d, "string", "ISO", zei->nmem);
853 static void zebraExplain_updateAccessInfo(ZebraExplainInfo zei, data1_node *n,
854 zebAccessInfo accessInfo)
856 data1_node *c = data1_search_tag(zei->dh, n->child, "accessInfo");
862 data1_pr_tree(zei->dh, n, stdout);
863 zebra_exit("zebraExplain_updateAccessInfo");
866 if ((p = accessInfo->attributeSetIds))
868 d = data1_mk_tag_uni(zei->dh, zei->nmem, "attributeSetIds", c);
869 for (; p; p = p->next)
870 data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
872 if ((p = accessInfo->schemas))
874 d = data1_mk_tag_uni(zei->dh, zei->nmem, "schemas", c);
875 for (; p; p = p->next)
876 data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
880 int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database,
881 int explain_database)
883 struct zebDatabaseInfoB *zdi;
884 data1_node *node_dbinfo, *node_adinfo;
885 const char *database_n = strrchr(database, '/');
890 database_n = database;
893 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
896 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
898 if (!STRCASECMP(zdi->databaseName, database_n))
903 /* it's new really. make it */
904 zdi = (struct zebDatabaseInfoB *) nmem_malloc(zei->nmem, sizeof(*zdi));
905 zdi->next = zei->databaseInfo;
906 zei->databaseInfo = zdi;
908 zdi->recordCount = 0;
909 zdi->recordBytes = 0;
911 zdi->databaseName = nmem_strdup(zei->nmem, database_n);
913 zdi->ordinalDatabase = zei->ordinalDatabase++;
915 zebraExplain_mergeAccessInfo(zei, 0, &zdi->accessInfo);
920 zdi->data1_database =
921 data1_read_sgml(zei->dh, zei->nmem,
922 "<explain><databaseInfo>DatabaseInfo\n"
924 if (!zdi->data1_database)
927 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
931 zebraExplain_initCommonInfo(zei, node_dbinfo);
932 zebraExplain_initAccessInfo(zei, node_dbinfo);
934 data1_mk_tag_data_text(zei->dh, node_dbinfo, "name",
935 database, zei->nmem);
937 if (explain_database)
938 data1_mk_tag_data_text(zei->dh, node_dbinfo, "explainDatabase",
941 data1_mk_tag_data_text(zei->dh, node_dbinfo, "userFee",
944 data1_mk_tag_data_text(zei->dh, node_dbinfo, "available",
948 data1_pr_tree(zei->dh, zdi->data1_database, stderr);
952 zei->curDatabaseInfo = zdi;
954 zdi->attributeDetails = (zebAttributeDetails)
955 nmem_malloc(zei->nmem, sizeof(*zdi->attributeDetails));
956 zdi->attributeDetails->readFlag = 0;
957 zdi->attributeDetails->sysno = 0;
958 zdi->attributeDetails->dirty = 1;
959 zdi->attributeDetails->SUInfo = 0;
960 zdi->attributeDetails->data1_tree =
961 data1_read_sgml(zei->dh, zei->nmem,
962 "<explain><attributeDetails>AttributeDetails\n"
965 node_adinfo = data1_search_tag(zei->dh, zdi->attributeDetails->data1_tree,
966 "/attributeDetails");
969 zebraExplain_initCommonInfo(zei, node_adinfo);
971 data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
977 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
978 struct zebraCategoryListInfo *zcl,
985 data1_node *node_ci, *node_categoryList;
987 static char *category[] = {
999 node_categoryList = zcl->data1_categoryList;
1002 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
1005 drec = createRecord(zei->records, &sysno);
1009 node_ci = data1_search_tag(zei->dh, node_categoryList,
1012 node_ci = data1_mk_tag(zei->dh, zei->nmem, "categories", 0 /* attr */,
1016 for (i = 0; category[i]; i++)
1018 data1_node *node_cat = data1_mk_tag(zei->dh, zei->nmem, "category",
1019 0 /* attr */, node_ci);
1021 data1_mk_tag_data_text(zei->dh, node_cat, "name",
1022 category[i], zei->nmem);
1024 /* extract *searchable* keys from it. We do this here, because
1025 record count, etc. is affected */
1027 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1029 /* convert to "SGML" and write it */
1031 data1_pr_tree(zei->dh, node_categoryList, stderr);
1033 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1034 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1035 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1036 drec->size[recInfo_storeData] = sgml_len;
1038 rec_put(zei->records, &drec);
1041 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
1042 zebAttributeDetails zad,
1043 const char *databaseName,
1049 data1_node *node_adinfo, *node_list, *node_zebra;
1050 struct zebSUInfoB *zsui;
1057 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1058 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1061 drec = createRecord(zei->records, &zad->sysno);
1064 assert(zad->data1_tree);
1066 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
1067 "/attributeDetails");
1068 zebraExplain_updateCommonInfo(zei, node_adinfo);
1070 /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
1071 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1072 "zebraInfo", node_adinfo);
1074 /* extract *searchable* keys from it. We do this here, because
1075 record count, etc. is affected */
1077 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1078 node_list = data1_mk_tag_uni(zei->dh, zei->nmem,
1079 "attrlist", node_zebra);
1080 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1082 data1_node *node_attr;
1083 node_attr = data1_mk_tag(zei->dh, zei->nmem, "attr", 0 /* attr */,
1086 data1_mk_tag_data_text(zei->dh, node_attr, "type",
1087 zsui->info.index_type, zei->nmem);
1088 data1_mk_tag_data_text(zei->dh, node_attr, "str",
1089 zsui->info.str, zei->nmem);
1090 data1_mk_tag_data_int(zei->dh, node_attr, "ordinal",
1091 zsui->info.ordinal, zei->nmem);
1093 data1_mk_tag_data_zint(zei->dh, node_attr, "dococcurrences",
1094 zsui->info.doc_occurrences, zei->nmem);
1095 data1_mk_tag_data_zint(zei->dh, node_attr, "termoccurrences",
1096 zsui->info.term_occurrences, zei->nmem);
1097 switch(zsui->info.cat)
1099 case zinfo_index_category_index:
1100 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1101 "index", zei->nmem); break;
1102 case zinfo_index_category_sort:
1103 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1104 "sort", zei->nmem); break;
1105 case zinfo_index_category_alwaysmatches:
1106 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1107 "alwaysmatches", zei->nmem); break;
1108 case zinfo_index_category_anchor:
1109 data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1110 "anchor", zei->nmem); break;
1113 /* convert to "SGML" and write it */
1115 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1117 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1119 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1120 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1121 drec->size[recInfo_storeData] = sgml_len;
1123 rec_put(zei->records, &drec);
1126 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
1127 struct zebDatabaseInfoB *zdi,
1133 data1_node *node_dbinfo, *node_count, *node_zebra;
1140 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1142 drec = createRecord(zei->records, &zdi->sysno);
1145 assert(zdi->data1_database);
1147 node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
1150 assert(node_dbinfo);
1151 zebraExplain_updateCommonInfo(zei, node_dbinfo);
1152 zebraExplain_updateAccessInfo(zei, node_dbinfo, zdi->accessInfo);
1155 node_count = data1_mk_tag_uni(zei->dh, zei->nmem,
1156 "recordCount", node_dbinfo);
1157 data1_mk_tag_data_zint(zei->dh, node_count, "recordCountActual",
1158 zdi->recordCount, zei->nmem);
1160 /* zebra info (private) */
1161 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1162 "zebraInfo", node_dbinfo);
1164 /* extract *searchable* keys from it. We do this here, because
1165 record count, etc. is affected */
1167 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1168 data1_mk_tag_data_zint(zei->dh, node_zebra,
1169 "recordBytes", zdi->recordBytes, zei->nmem);
1171 data1_mk_tag_data_zint(zei->dh, node_zebra,
1172 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1174 /* convert to "SGML" and write it */
1176 data1_pr_tree(zei->dh, zdi->data1_database, stderr);
1178 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1180 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1181 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1182 drec->size[recInfo_storeData] = sgml_len;
1184 rec_put(zei->records, &drec);
1187 static void writeAttributeValues(ZebraExplainInfo zei,
1188 data1_node *node_values,
1189 data1_attset *attset)
1192 data1_attset_child *c;
1197 for (c = attset->children; c; c = c->next)
1198 writeAttributeValues(zei, node_values, c->child);
1199 for (atts = attset->atts; atts; atts = atts->next)
1201 data1_node *node_value;
1203 node_value = data1_mk_tag(zei->dh, zei->nmem, "attributeValue",
1204 0 /* attr */, node_values);
1205 data1_mk_tag_data_text(zei->dh, node_value, "name",
1206 atts->name, zei->nmem);
1207 node_value = data1_mk_tag(zei->dh, zei->nmem, "value",
1208 0 /* attr */, node_value);
1209 data1_mk_tag_data_int(zei->dh, node_value, "numeric",
1210 atts->value, zei->nmem);
1215 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
1222 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1223 data1_node *node_values;
1224 struct data1_attset *attset = 0;
1227 attset = data1_attset_search_id(zei->dh, o->oid);
1230 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1231 attset ? attset->name : "<unknown>");
1234 drec = createRecord(zei->records, &o->sysno);
1238 data1_read_sgml(zei->dh, zei->nmem,
1239 "<explain><attributeSetInfo>AttributeSetInfo\n"
1242 node_attinfo = data1_search_tag(zei->dh, node_root,
1243 "/attributeSetInfo");
1245 assert(node_attinfo);
1246 zebraExplain_initCommonInfo(zei, node_attinfo);
1247 zebraExplain_updateCommonInfo(zei, node_attinfo);
1249 data1_mk_tag_data_oid(zei->dh, node_attinfo,
1250 "oid", o->oid, zei->nmem);
1251 if (attset && attset->name)
1252 data1_mk_tag_data_text(zei->dh, node_attinfo,
1253 "name", attset->name, zei->nmem);
1255 node_attributes = data1_mk_tag_uni(zei->dh, zei->nmem,
1256 "attributes", node_attinfo);
1257 node_atttype = data1_mk_tag_uni(zei->dh, zei->nmem,
1258 "attributeType", node_attributes);
1259 data1_mk_tag_data_text(zei->dh, node_atttype,
1260 "name", "Use", zei->nmem);
1261 data1_mk_tag_data_text(zei->dh, node_atttype,
1262 "description", "Use Attribute", zei->nmem);
1263 data1_mk_tag_data_int(zei->dh, node_atttype,
1264 "type", 1, zei->nmem);
1265 node_values = data1_mk_tag(zei->dh, zei->nmem,
1266 "attributeValues", 0 /* attr */, node_atttype);
1268 writeAttributeValues(zei, node_values, attset);
1270 /* extract *searchable* keys from it. We do this here, because
1271 record count, etc. is affected */
1273 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1274 /* convert to "SGML" and write it */
1276 data1_pr_tree(zei->dh, node_root, stderr);
1278 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1279 drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1280 memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1281 drec->size[recInfo_storeData] = sgml_len;
1283 rec_put(zei->records, &drec);
1286 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush)
1288 struct zebDatabaseInfoB *zdi;
1289 data1_node *node_tgtinfo, *node_list, *node_zebra;
1298 trec = rec_get_root(zei->records);
1299 xfree(trec->info[recInfo_storeData]);
1301 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
1303 assert(node_tgtinfo);
1305 zebraExplain_updateCommonInfo(zei, node_tgtinfo);
1306 zebraExplain_updateAccessInfo(zei, node_tgtinfo, zei->accessInfo);
1308 node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1309 "zebraInfo", node_tgtinfo);
1310 /* convert to "SGML" and write it */
1312 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1314 data1_mk_tag_data_text(zei->dh, node_zebra, "version",
1315 ZEBRAVER, zei->nmem);
1316 node_list = data1_mk_tag(zei->dh, zei->nmem,
1317 "databaseList", 0 /* attr */, node_zebra);
1318 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1320 data1_node *node_db;
1321 node_db = data1_mk_tag(zei->dh, zei->nmem,
1322 "database", 0 /* attr */, node_list);
1323 data1_mk_tag_data_text(zei->dh, node_db, "name",
1324 zdi->databaseName, zei->nmem);
1325 data1_mk_tag_data_zint(zei->dh, node_db, "id",
1326 zdi->sysno, zei->nmem);
1327 data1_mk_tag_data_zint(zei->dh, node_db, "attributeDetailsId",
1328 zdi->attributeDetails->sysno, zei->nmem);
1330 data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalSU",
1331 zei->ordinalSU, zei->nmem);
1333 data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalDatabase",
1334 zei->ordinalDatabase, zei->nmem);
1336 data1_mk_tag_data_zint(zei->dh, node_zebra, "runNumber",
1337 zei->runNumber, zei->nmem);
1340 data1_pr_tree(zei->dh, zei->data1_target, stderr);
1342 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1344 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1345 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
1346 trec->size[recInfo_storeData] = sgml_len;
1348 rec_put(zei->records, &trec);
1351 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
1352 zinfo_index_category_t cat,
1353 const char *index_type,
1356 struct zebSUInfoB **zsui;
1358 assert(zei->curDatabaseInfo);
1359 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1360 *zsui; zsui = &(*zsui)->next)
1361 if ( (index_type == 0
1362 || !strcmp((*zsui)->info.index_type, index_type))
1363 && (*zsui)->info.cat == cat
1364 && !yaz_matchstr((*zsui)->info.str, str))
1366 struct zebSUInfoB *zsui_this = *zsui;
1368 /* take it out of the list and move to front */
1369 *zsui = (*zsui)->next;
1370 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1371 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1373 return zsui_this->info.ordinal;
1378 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1379 int (*f)(void *handle, int ord,
1380 const char *index_type,
1381 const char *string_index,
1382 zinfo_index_category_t cat))
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,
1390 zsui->info.index_type, zsui->info.str,
1397 struct zebSUInfoB *zebraExplain_get_sui_info(ZebraExplainInfo zei, int ord,
1401 struct zebDatabaseInfoB *zdb;
1403 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1405 struct zebSUInfoB **zsui;
1407 if (zdb->attributeDetails->readFlag)
1408 zebraExplain_readAttributeDetails(zei, zdb->attributeDetails);
1410 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1411 zsui = &(*zsui)->next)
1412 if ((*zsui)->info.ordinal == ord)
1414 struct zebSUInfoB *zsui_this = *zsui;
1416 /* take it out of the list and move to front */
1417 *zsui = (*zsui)->next;
1418 zsui_this->next = zdb->attributeDetails->SUInfo;
1419 zdb->attributeDetails->SUInfo = zsui_this;
1422 zdb->attributeDetails->dirty = 1;
1424 *db = zdb->databaseName;
1433 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1434 int term_delta, int doc_delta)
1436 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1439 zsui->info.term_occurrences += term_delta;
1440 zsui->info.doc_occurrences += doc_delta;
1446 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1447 zint *term_occurrences,
1448 zint *doc_occurrences)
1450 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1453 *term_occurrences = zsui->info.term_occurrences;
1454 *doc_occurrences = zsui->info.doc_occurrences;
1460 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1462 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1464 return zsui->info.doc_occurrences;
1468 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1470 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1472 return zsui->info.term_occurrences;
1476 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1477 const char **index_type,
1479 const char **string_index)
1481 struct zebSUInfoB *zsui;
1488 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1492 *string_index = zsui->info.str;
1494 *index_type = zsui->info.index_type;
1502 zebAccessObject zebraExplain_announceOid(ZebraExplainInfo zei,
1503 zebAccessObject *op,
1508 for (ao = *op; ao; ao = ao->next)
1509 if (!oid_oidcmp(oid, ao->oid))
1513 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
1516 ao->oid = odr_oiddup_nmem(zei->nmem, oid);
1523 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1524 zinfo_index_category_t cat,
1525 const char *index_type)
1527 struct zebSUInfoB *zsui;
1529 assert(zei->curDatabaseInfo);
1530 zsui = (struct zebSUInfoB *) nmem_malloc(zei->nmem, sizeof(*zsui));
1531 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1532 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1533 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1535 zsui->info.index_type = nmem_strdup(zei->nmem, index_type);
1536 zsui->info.cat = cat;
1537 zsui->info.doc_occurrences = 0;
1538 zsui->info.term_occurrences = 0;
1539 zsui->info.ordinal = (zei->ordinalSU)++;
1543 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1544 zinfo_index_category_t cat,
1545 const char *index_type,
1546 const char *index_name)
1548 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1550 zsui->info.str = nmem_strdup(zei->nmem, index_name);
1551 return zsui->info.ordinal;
1554 void zebraExplain_addSchema(ZebraExplainInfo zei, Odr_oid *oid)
1556 zebraExplain_announceOid(zei, &zei->accessInfo->schemas, oid);
1557 zebraExplain_announceOid(zei, &zei->curDatabaseInfo->
1558 accessInfo->schemas, oid);
1561 void zebraExplain_recordBytesIncrement(ZebraExplainInfo zei, int adjust_num)
1563 assert(zei->curDatabaseInfo);
1567 zei->curDatabaseInfo->recordBytes += adjust_num;
1568 zei->curDatabaseInfo->dirty = 1;
1572 void zebraExplain_recordCountIncrement(ZebraExplainInfo zei, int adjust_num)
1574 assert(zei->curDatabaseInfo);
1578 zei->curDatabaseInfo->recordCount += adjust_num;
1579 zei->curDatabaseInfo->dirty = 1;
1583 zint zebraExplain_runNumberIncrement(ZebraExplainInfo zei, int adjust_num)
1589 return zei->runNumber += adjust_num;
1592 RecordAttr *rec_init_attr(ZebraExplainInfo zei, Record rec)
1594 RecordAttr *recordAttr;
1596 if (rec->info[recInfo_attr])
1597 return (RecordAttr *) rec->info[recInfo_attr];
1598 recordAttr = (RecordAttr *) xmalloc(sizeof(*recordAttr));
1600 memset(recordAttr, '\0', sizeof(*recordAttr));
1601 rec->info[recInfo_attr] = (char *) recordAttr;
1602 rec->size[recInfo_attr] = sizeof(*recordAttr);
1604 recordAttr->recordSize = 0;
1605 recordAttr->recordOffset = 0;
1606 recordAttr->runNumber = zei->runNumber;
1607 recordAttr->staticrank = 0;
1611 static void att_loadset(void *p, const char *n, const char *name)
1613 data1_handle dh = (data1_handle) p;
1614 if (!data1_get_attset(dh, name))
1615 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1618 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1620 if (!zei->curDatabaseInfo)
1622 return zei->curDatabaseInfo->ordinalDatabase;
1625 void zebraExplain_loadAttsets(data1_handle dh, Res res)
1627 res_trav(res, "attset", dh, att_loadset);
1631 zebraExplain_addSU adds to AttributeDetails for a database and
1632 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1633 exist for the database.
1635 If the database doesn't exist globally (in TargetInfo) an
1636 AttributeSetInfo must be added (globally).
1641 * c-file-style: "Stroustrup"
1642 * indent-tabs-mode: nil
1644 * vim: shiftwidth=4 tabstop=8 expandtab