1 /* $Id: zinfo.c,v 1.68 2006-08-14 10:40:15 adam Exp $
2 Copyright (C) 1995-2006
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sys/types.h>
29 #include <idzebra/version.h>
36 zinfo_index_category_t cat;
37 #define ZEB_SU_SET_USE 1
45 zint term_occurrences;
49 struct zebSUInfo info;
50 struct zebSUInfoB *next;
53 typedef struct zebAccessObjectB *zebAccessObject;
54 struct zebAccessObjectB {
61 typedef struct zebAccessInfoB *zebAccessInfo;
62 struct zebAccessInfoB {
63 zebAccessObject attributeSetIds;
64 zebAccessObject schemas;
68 struct zebSUInfoB *SUInfo;
72 data1_node *data1_tree;
73 } *zebAttributeDetails;
75 struct zebDatabaseInfoB {
76 zebAttributeDetails attributeDetails;
79 data1_node *data1_database;
80 zint recordCount; /* records in db */
81 zint recordBytes; /* size of records */
82 SYSNO sysno; /* sysno of database info */
83 int readFlag; /* 1: read is needed when referenced; 0 if not */
84 int dirty; /* 1: database is dirty: write is needed */
85 struct zebDatabaseInfoB *next;
86 zebAccessInfo accessInfo;
89 struct zebraExplainAttset {
92 struct zebraExplainAttset *next;
95 struct zebraCategoryListInfo {
98 data1_node *data1_categoryList;
101 struct zebraExplainInfo {
110 struct zebraExplainAttset *attsets;
112 data1_node *data1_target;
113 struct zebraCategoryListInfo *categoryList;
114 struct zebDatabaseInfoB *databaseInfo;
115 struct zebDatabaseInfoB *curDatabaseInfo;
116 zebAccessInfo accessInfo;
117 char date[15]; /* YYYY MMDD HH MM SS */
118 ZebraExplainUpdateFunc *updateFunc;
122 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
123 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
125 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
127 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
130 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
131 struct zebDatabaseInfoB *zdi,
133 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
134 zebAttributeDetails zad,
135 const char *databaseName,
137 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
138 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
141 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
142 struct zebraCategoryListInfo *zcl,
146 static Record createRecord(Records records, SYSNO *sysno)
151 rec = rec_get(records, *sysno);
154 xfree(rec->info[recInfo_storeData]);
158 rec = rec_new(records);
163 rec->info[recInfo_fileType] =
164 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
165 rec->info[recInfo_databaseName] =
166 rec_strdup("IR-Explain-1",
167 &rec->size[recInfo_databaseName]);
172 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
176 zei->updateHandle = handle;
179 struct zebDatabaseInfoB *zdi;
182 /* write each database info record */
183 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
185 zebraExplain_writeDatabase(zei, zdi, 1);
186 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
187 zdi->databaseName, 1);
189 zebraExplain_writeTarget(zei, 1);
190 zebraExplain_writeCategoryList(zei,
193 assert(zei->accessInfo);
194 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
196 zebraExplain_writeAttributeSet(zei, o, 1);
197 for (o = zei->accessInfo->schemas; o; o = o->next)
200 /* zebraExplain_writeSchema(zei, o, 1); */
203 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
205 zebraExplain_writeDatabase(zei, zdi, 0);
206 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
207 zdi->databaseName, 0);
209 zebraExplain_writeTarget(zei, 0);
213 void zebraExplain_close(ZebraExplainInfo zei)
216 yaz_log(YLOG_LOG, "zebraExplain_close");
220 zebraExplain_flush(zei, zei->updateHandle);
221 nmem_destroy(zei->nmem);
224 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
229 for (np = n->child; np; np = np->next)
236 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
238 len = np->child->u.data.len;
241 memcpy(str, np->child->u.data.data, len);
244 oid = odr_getoidbystr_nmem(zei->nmem, str);
246 for (ao = *op; ao; ao = ao->next)
247 if (!oid_oidcmp(oid, ao->oid))
254 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
264 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
265 zebAccessInfo *accessInfo)
271 *accessInfo = (zebAccessInfo)
272 nmem_malloc(zei->nmem, sizeof(**accessInfo));
273 (*accessInfo)->attributeSetIds = NULL;
274 (*accessInfo)->schemas = NULL;
278 if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
280 if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
281 zebraExplain_mergeOids(zei, np,
282 &(*accessInfo)->attributeSetIds);
283 if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
284 zebraExplain_mergeOids(zei, np,
285 &(*accessInfo)->schemas);
294 databaseList (list of databases)
299 targetInfo: TargetInfo
306 dateAdded: 20030630190601
307 dateChanged: 20030630190601
313 oid: 1.2.840.10003.3.2
314 oid: 1.2.840.10003.3.5
315 oid: 1.2.840.10003.3.1
317 oid: 1.2.840.10003.13.1000.81.2
318 oid: 1.2.840.10003.13.2
325 attributeDetailsId: 51
329 attributeDetailsId: 53
332 nextResultSetPosition = 2
335 ZebraExplainInfo zebraExplain_open(
336 Records records, data1_handle dh,
340 ZebraExplainUpdateFunc *updateFunc)
343 ZebraExplainInfo zei;
344 struct zebDatabaseInfoB **zdip;
347 NMEM nmem = nmem_create();
350 yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
352 zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
353 zei->databaseInfo = 0;
354 zei->write_flag = writeFlag;
355 zei->updateHandle = updateHandle;
356 zei->updateFunc = updateFunc;
358 zei->ordinalDatabase = 1;
359 zei->curDatabaseInfo = NULL;
360 zei->records = records;
364 data1_get_absyn (zei->dh, "explain", DATA1_XPATH_INDEXING_DISABLE);
368 zei->categoryList = (struct zebraCategoryListInfo *)
369 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
370 zei->categoryList->sysno = 0;
371 zei->categoryList->dirty = 0;
372 zei->categoryList->data1_categoryList = NULL;
374 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
377 tm = localtime(&our_time);
378 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
379 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
380 tm->tm_hour, tm->tm_min, tm->tm_sec);
382 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
385 zdip = &zei->databaseInfo;
386 trec = rec_get_root(records); /* get "root" record */
391 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
392 if (trec) /* targetInfo already exists ... */
394 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
396 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
398 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
400 if (!zei->data1_target)
403 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
404 nmem_destroy(zei->nmem);
408 data1_pr_tree(zei->dh, zei->data1_target, stderr);
410 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
412 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
415 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
420 node_list = data1_search_tag(zei->dh, node_zebra->child,
423 np = node_list->child;
425 for(; np; np = np->next)
427 data1_node *node_name = NULL;
428 data1_node *node_id = NULL;
429 data1_node *node_aid = NULL;
431 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
433 for(np2 = np->child; np2; np2 = np2->next)
435 if (np2->which != DATA1N_tag)
437 if (!strcmp(np2->u.tag.tag, "name"))
438 node_name = np2->child;
439 else if (!strcmp(np2->u.tag.tag, "id"))
440 node_id = np2->child;
441 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
442 node_aid = np2->child;
444 assert(node_id && node_name && node_aid);
446 *zdip =(struct zebDatabaseInfoB *)
447 nmem_malloc(zei->nmem, sizeof(**zdip));
448 (*zdip)->readFlag = 1;
450 (*zdip)->data1_database = NULL;
451 (*zdip)->recordCount = 0;
452 (*zdip)->recordBytes = 0;
453 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
455 (*zdip)->databaseName = (char *)
456 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
457 memcpy((*zdip)->databaseName, node_name->u.data.data,
458 node_name->u.data.len);
459 (*zdip)->databaseName[node_name->u.data.len] = '\0';
460 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
461 node_id->u.data.len);
462 (*zdip)->attributeDetails = (zebAttributeDetails)
463 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
464 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
465 node_aid->u.data.len);
466 (*zdip)->attributeDetails->readFlag = 1;
467 (*zdip)->attributeDetails->dirty = 0;
468 (*zdip)->attributeDetails->SUInfo = NULL;
470 zdip = &(*zdip)->next;
474 np = data1_search_tag(zei->dh, node_zebra->child,
477 assert (np && np->which == DATA1N_data);
478 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
480 np = data1_search_tag(zei->dh, node_zebra->child,
483 assert (np && np->which == DATA1N_data);
484 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
486 np = data1_search_tag(zei->dh, node_zebra->child,
489 assert (np && np->which == DATA1N_data);
490 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
491 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
496 else /* create initial targetInfo */
498 data1_node *node_tgtinfo;
507 data1_read_sgml(zei->dh, zei->nmem,
508 "<explain><targetInfo>TargetInfo\n"
510 "<namedResultSets>1</>\n"
511 "<multipleDBSearch>1</>\n"
512 "<nicknames><name>Zebra</></>\n"
514 if (!zei->data1_target)
516 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
517 nmem_destroy(zei->nmem);
520 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
522 assert(node_tgtinfo);
524 zebraExplain_initCommonInfo(zei, node_tgtinfo);
525 zebraExplain_initAccessInfo(zei, node_tgtinfo);
527 /* write now because we want to be sure about the sysno */
528 trec = rec_new(records);
531 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
532 nmem_destroy(zei->nmem);
535 trec->info[recInfo_fileType] =
536 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
537 trec->info[recInfo_databaseName] =
538 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
540 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
541 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
542 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
543 trec->size[recInfo_storeData] = sgml_len;
545 rec_put(records, &trec);
549 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
551 if (!zei->categoryList->dirty)
553 struct zebraCategoryListInfo *zcl = zei->categoryList;
557 zcl->data1_categoryList =
558 data1_read_sgml(zei->dh, zei->nmem,
559 "<explain><categoryList>CategoryList\n"
562 if (zcl->data1_categoryList)
564 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
567 zebraExplain_initCommonInfo(zei, node_cl);
574 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
575 zebAttributeDetails zad)
578 struct zebSUInfoB **zsuip = &zad->SUInfo;
579 data1_node *node_adinfo, *node_zebra, *node_list, *np;
582 rec = rec_get(zei->records, zad->sysno);
584 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
586 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
587 "/attributeDetails");
588 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
590 node_list = data1_search_tag(zei->dh, node_zebra->child,
592 for (np = node_list->child; np; np = np->next)
594 data1_node *node_str = NULL;
595 data1_node *node_ordinal = NULL;
596 data1_node *node_type = NULL;
597 data1_node *node_cat = NULL;
598 data1_node *node_doc_occurrences = NULL;
599 data1_node *node_term_occurrences = NULL;
602 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
604 for (np2 = np->child; np2; np2 = np2->next)
606 if (np2->which != DATA1N_tag || !np2->child ||
607 np2->child->which != DATA1N_data)
609 if (!strcmp(np2->u.tag.tag, "str"))
610 node_str = np2->child;
611 else if (!strcmp(np2->u.tag.tag, "ordinal"))
612 node_ordinal = np2->child;
613 else if (!strcmp(np2->u.tag.tag, "type"))
614 node_type = np2->child;
615 else if (!strcmp(np2->u.tag.tag, "cat"))
616 node_cat = np2->child;
617 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
618 node_doc_occurrences = np2->child;
619 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
620 node_term_occurrences = np2->child;
623 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
627 assert(node_ordinal);
629 *zsuip = (struct zebSUInfoB *)
630 nmem_malloc(zei->nmem, sizeof(**zsuip));
632 if (node_type && node_type->u.data.len > 0)
633 (*zsuip)->info.index_type = node_type->u.data.data[0];
636 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
637 (*zsuip)->info.index_type = 'w';
639 if (node_cat && node_cat->u.data.len > 0)
641 zinfo_index_category_t cat;
643 data1_node *np = node_cat;
644 if (!strncmp(np->u.data.data, "index", np->u.data.len))
645 cat = zinfo_index_category_index;
646 else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
647 cat = zinfo_index_category_sort;
648 else if (!strncmp(np->u.data.data, "alwaysmatches",
650 cat = zinfo_index_category_alwaysmatches;
651 else if (!strncmp(np->u.data.data, "anchor",
653 cat = zinfo_index_category_anchor;
656 yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
657 np->u.data.len, np->u.data.data);
658 cat = zinfo_index_category_index;
660 (*zsuip)->info.cat = cat;
663 (*zsuip)->info.cat = zinfo_index_category_index;
665 if (node_doc_occurrences)
667 data1_node *np = node_doc_occurrences;
668 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
671 if (node_term_occurrences)
673 data1_node *np = node_term_occurrences;
674 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
679 (*zsuip)->info.which = ZEB_SU_STR;
681 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
682 node_str->u.data.data,
683 node_str->u.data.len);
687 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
690 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
691 node_ordinal->u.data.len);
692 zsuip = &(*zsuip)->next;
699 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
700 struct zebDatabaseInfoB *zdi)
703 data1_node *node_dbinfo, *node_zebra, *np;
706 rec = rec_get (zei->records, zdi->sysno);
708 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
710 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
712 assert (node_dbinfo);
713 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
715 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
718 && (np = data1_search_tag (zei->dh, node_zebra->child,
720 && np->child && np->child->which == DATA1N_data)
721 zdi->recordBytes = atoi_zn (np->child->u.data.data,
722 np->child->u.data.len);
725 && (np = data1_search_tag (zei->dh, node_zebra->child,
727 && np->child && np->child->which == DATA1N_data)
728 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
729 np->child->u.data.len);
731 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
733 (np = data1_search_tag (zei->dh, np->child,
734 "recordCountActual")) &&
735 np->child->which == DATA1N_data)
737 zdi->recordCount = atoi_zn (np->child->u.data.data,
738 np->child->u.data.len);
744 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
746 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
750 if (*zdip == zei->curDatabaseInfo)
752 struct zebDatabaseInfoB *zdi = *zdip;
756 zei->updateHandle = update_handle;
758 if (zdi->attributeDetails)
760 /* remove attribute details keys and delete it */
761 zebAttributeDetails zad = zdi->attributeDetails;
763 rec = rec_get(zei->records, zad->sysno);
764 (*zei->updateFunc)(zei->updateHandle, rec, 0);
767 /* remove database record keys and delete it */
768 rec = rec_get (zei->records, zdi->sysno);
769 (*zei->updateFunc)(zei->updateHandle, rec, 0);
772 /* remove from list */
775 /* current database is IR-Explain-1 */
778 zdip = &(*zdip)->next;
783 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
785 struct zebDatabaseInfoB *zdi;
786 const char *database_n = strrchr (database, '/');
791 database_n = database;
794 if (zei->curDatabaseInfo &&
795 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
797 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
799 if (!STRCASECMP (zdi->databaseName, database_n))
805 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
810 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
812 zebraExplain_readDatabase (zei, zdi);
814 if (zdi->attributeDetails->readFlag)
817 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
819 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
821 zei->curDatabaseInfo = zdi;
825 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
827 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
828 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
829 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
830 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
833 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
835 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
837 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
841 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
843 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
844 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
845 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
848 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
849 zebAccessInfo accessInfo)
851 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
857 data1_pr_tree (zei->dh, n, stdout);
862 if ((p = accessInfo->attributeSetIds))
864 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
865 for (; p; p = p->next)
866 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
868 if ((p = accessInfo->schemas))
870 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
871 for (; p; p = p->next)
872 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
876 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
877 int explain_database)
879 struct zebDatabaseInfoB *zdi;
880 data1_node *node_dbinfo, *node_adinfo;
881 const char *database_n = strrchr (database, '/');
886 database_n = database;
889 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
892 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
894 if (!STRCASECMP (zdi->databaseName, database_n))
899 /* it's new really. make it */
900 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
901 zdi->next = zei->databaseInfo;
902 zei->databaseInfo = zdi;
904 zdi->recordCount = 0;
905 zdi->recordBytes = 0;
907 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
909 zdi->ordinalDatabase = zei->ordinalDatabase++;
911 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
916 zdi->data1_database =
917 data1_read_sgml (zei->dh, zei->nmem,
918 "<explain><databaseInfo>DatabaseInfo\n"
920 if (!zdi->data1_database)
923 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
925 assert (node_dbinfo);
927 zebraExplain_initCommonInfo (zei, node_dbinfo);
928 zebraExplain_initAccessInfo (zei, node_dbinfo);
930 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
931 database, zei->nmem);
933 if (explain_database)
934 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
937 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
940 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
944 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
948 zei->curDatabaseInfo = zdi;
950 zdi->attributeDetails = (zebAttributeDetails)
951 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
952 zdi->attributeDetails->readFlag = 0;
953 zdi->attributeDetails->sysno = 0;
954 zdi->attributeDetails->dirty = 1;
955 zdi->attributeDetails->SUInfo = NULL;
956 zdi->attributeDetails->data1_tree =
957 data1_read_sgml (zei->dh, zei->nmem,
958 "<explain><attributeDetails>AttributeDetails\n"
961 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
962 "/attributeDetails");
963 assert (node_adinfo);
965 zebraExplain_initCommonInfo (zei, node_adinfo);
971 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
972 struct zebraCategoryListInfo *zcl,
979 data1_node *node_ci, *node_categoryList;
981 static char *category[] = {
993 node_categoryList = zcl->data1_categoryList;
996 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
999 drec = createRecord (zei->records, &sysno);
1003 node_ci = data1_search_tag (zei->dh, node_categoryList,
1006 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
1010 for (i = 0; category[i]; i++)
1012 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
1013 0 /* attr */, node_ci);
1015 data1_mk_tag_data_text (zei->dh, node_cat, "name",
1016 category[i], zei->nmem);
1018 /* extract *searchable* keys from it. We do this here, because
1019 record count, etc. is affected */
1021 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1023 /* convert to "SGML" and write it */
1025 data1_pr_tree (zei->dh, node_categoryList, stderr);
1027 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1028 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1029 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1030 drec->size[recInfo_storeData] = sgml_len;
1032 rec_put (zei->records, &drec);
1035 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1036 zebAttributeDetails zad,
1037 const char *databaseName,
1043 data1_node *node_adinfo, *node_list, *node_zebra;
1044 struct zebSUInfoB *zsui;
1051 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1054 drec = createRecord (zei->records, &zad->sysno);
1057 assert (zad->data1_tree);
1059 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1060 "/attributeDetails");
1061 zebraExplain_updateCommonInfo (zei, node_adinfo);
1063 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1064 databaseName, zei->nmem);
1066 /* extract *searchable* keys from it. We do this here, because
1067 record count, etc. is affected */
1069 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1070 /* zebra info (private) */
1071 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1072 "zebraInfo", node_adinfo);
1073 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1074 "attrlist", node_zebra);
1075 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1077 data1_node *node_attr;
1078 char index_type_str[2];
1080 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1083 index_type_str[0] = zsui->info.index_type;
1084 index_type_str[1] = '\0';
1085 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1086 index_type_str, zei->nmem);
1087 if (zsui->info.which == ZEB_SU_STR)
1089 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1090 zsui->info.u.str, zei->nmem);
1092 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1093 zsui->info.ordinal, zei->nmem);
1095 data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
1096 zsui->info.doc_occurrences, zei->nmem);
1097 data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
1098 zsui->info.term_occurrences, zei->nmem);
1099 switch(zsui->info.cat)
1101 case zinfo_index_category_index:
1102 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1103 "index", zei->nmem); break;
1104 case zinfo_index_category_sort:
1105 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1106 "sort", zei->nmem); break;
1107 case zinfo_index_category_alwaysmatches:
1108 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1109 "alwaysmatches", zei->nmem); break;
1110 case zinfo_index_category_anchor:
1111 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1112 "anchor", zei->nmem); break;
1115 /* convert to "SGML" and write it */
1117 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1119 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1121 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1122 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1123 drec->size[recInfo_storeData] = sgml_len;
1125 rec_put (zei->records, &drec);
1128 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1129 struct zebDatabaseInfoB *zdi,
1135 data1_node *node_dbinfo, *node_count, *node_zebra;
1142 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1144 drec = createRecord (zei->records, &zdi->sysno);
1147 assert (zdi->data1_database);
1149 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1152 assert (node_dbinfo);
1153 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1154 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1156 /* extract *searchable* keys from it. We do this here, because
1157 record count, etc. is affected */
1159 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1161 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1162 "recordCount", node_dbinfo);
1163 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1164 zdi->recordCount, zei->nmem);
1166 /* zebra info (private) */
1167 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1168 "zebraInfo", node_dbinfo);
1169 data1_mk_tag_data_zint (zei->dh, node_zebra,
1170 "recordBytes", zdi->recordBytes, zei->nmem);
1172 data1_mk_tag_data_zint(zei->dh, node_zebra,
1173 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1175 /* convert to "SGML" and write it */
1177 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1179 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1181 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1182 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1183 drec->size[recInfo_storeData] = sgml_len;
1185 rec_put (zei->records, &drec);
1188 static void writeAttributeValues (ZebraExplainInfo zei,
1189 data1_node *node_values,
1190 data1_attset *attset)
1193 data1_attset_child *c;
1198 for (c = attset->children; c; c = c->next)
1199 writeAttributeValues (zei, node_values, c->child);
1200 for (atts = attset->atts; atts; atts = atts->next)
1202 data1_node *node_value;
1204 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1205 0 /* attr */, node_values);
1206 data1_mk_tag_data_text (zei->dh, node_value, "name",
1207 atts->name, zei->nmem);
1208 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1209 0 /* attr */, node_value);
1210 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1211 atts->value, zei->nmem);
1216 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1223 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1224 data1_node *node_values;
1225 struct oident *entp;
1226 struct data1_attset *attset = NULL;
1228 if ((entp = oid_getentbyoid (o->oid)))
1229 attset = data1_attset_search_id (zei->dh, entp->value);
1232 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1233 attset ? attset->name : "<unknown>");
1236 drec = createRecord (zei->records, &o->sysno);
1240 data1_read_sgml (zei->dh, zei->nmem,
1241 "<explain><attributeSetInfo>AttributeSetInfo\n"
1244 node_attinfo = data1_search_tag (zei->dh, node_root,
1245 "/attributeSetInfo");
1247 assert (node_attinfo);
1248 zebraExplain_initCommonInfo (zei, node_attinfo);
1249 zebraExplain_updateCommonInfo (zei, node_attinfo);
1251 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1252 "oid", o->oid, zei->nmem);
1253 if (attset && attset->name)
1254 data1_mk_tag_data_text (zei->dh, node_attinfo,
1255 "name", attset->name, zei->nmem);
1257 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1258 "attributes", node_attinfo);
1259 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1260 "attributeType", node_attributes);
1261 data1_mk_tag_data_text (zei->dh, node_atttype,
1262 "name", "Use", zei->nmem);
1263 data1_mk_tag_data_text (zei->dh, node_atttype,
1264 "description", "Use Attribute", zei->nmem);
1265 data1_mk_tag_data_int (zei->dh, node_atttype,
1266 "type", 1, zei->nmem);
1267 node_values = data1_mk_tag (zei->dh, zei->nmem,
1268 "attributeValues", 0 /* attr */, node_atttype);
1270 writeAttributeValues (zei, node_values, attset);
1272 /* extract *searchable* keys from it. We do this here, because
1273 record count, etc. is affected */
1275 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1276 /* convert to "SGML" and write it */
1278 data1_pr_tree (zei->dh, node_root, stderr);
1280 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1281 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1282 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1283 drec->size[recInfo_storeData] = sgml_len;
1285 rec_put (zei->records, &drec);
1288 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1290 struct zebDatabaseInfoB *zdi;
1291 data1_node *node_tgtinfo, *node_list, *node_zebra;
1300 trec = rec_get_root(zei->records);
1301 xfree (trec->info[recInfo_storeData]);
1303 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1305 assert (node_tgtinfo);
1307 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1308 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1310 /* convert to "SGML" and write it */
1312 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1314 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1315 "zebraInfo", node_tgtinfo);
1316 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1317 ZEBRAVER, zei->nmem);
1318 node_list = data1_mk_tag (zei->dh, zei->nmem,
1319 "databaseList", 0 /* attr */, node_zebra);
1320 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1322 data1_node *node_db;
1323 node_db = data1_mk_tag (zei->dh, zei->nmem,
1324 "database", 0 /* attr */, node_list);
1325 data1_mk_tag_data_text (zei->dh, node_db, "name",
1326 zdi->databaseName, zei->nmem);
1327 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1328 zdi->sysno, zei->nmem);
1329 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1330 zdi->attributeDetails->sysno, zei->nmem);
1332 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1333 zei->ordinalSU, zei->nmem);
1335 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
1336 zei->ordinalDatabase, zei->nmem);
1338 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1339 zei->runNumber, zei->nmem);
1342 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1344 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1346 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1347 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1348 trec->size[recInfo_storeData] = sgml_len;
1350 rec_put (zei->records, &trec);
1353 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
1354 zinfo_index_category_t cat,
1358 struct zebSUInfoB **zsui;
1360 assert (zei->curDatabaseInfo);
1361 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1362 *zsui; zsui = &(*zsui)->next)
1363 if ((*zsui)->info.index_type == index_type
1364 && (*zsui)->info.cat == cat
1365 && (*zsui)->info.which == ZEB_SU_STR
1366 && !yaz_matchstr((*zsui)->info.u.str, str))
1368 struct zebSUInfoB *zsui_this = *zsui;
1370 /* take it out of the list and move to front */
1371 *zsui = (*zsui)->next;
1372 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1373 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1375 return zsui_this->info.ordinal;
1380 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1381 int (*f)(void *handle, int ord))
1383 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1386 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1387 for ( ;zsui; zsui = zsui->next)
1388 (*f)(handle, zsui->info.ordinal);
1394 struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
1398 struct zebDatabaseInfoB *zdb;
1400 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1402 struct zebSUInfoB **zsui;
1404 if (zdb->attributeDetails->readFlag)
1405 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1407 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1408 zsui = &(*zsui)->next)
1409 if ((*zsui)->info.ordinal == ord)
1411 struct zebSUInfoB *zsui_this = *zsui;
1413 /* take it out of the list and move to front */
1414 *zsui = (*zsui)->next;
1415 zsui_this->next = zdb->attributeDetails->SUInfo;
1416 zdb->attributeDetails->SUInfo = zsui_this;
1419 zdb->attributeDetails->dirty = 1;
1421 *db = zdb->databaseName;
1430 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1431 int term_delta, int doc_delta)
1433 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1436 zsui->info.term_occurrences += term_delta;
1437 zsui->info.doc_occurrences += doc_delta;
1443 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1444 zint *term_occurrences,
1445 zint *doc_occurrences)
1447 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1450 *term_occurrences = zsui->info.term_occurrences;
1451 *doc_occurrences = zsui->info.doc_occurrences;
1457 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1459 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1461 return zsui->info.doc_occurrences;
1465 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1467 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1469 return zsui->info.term_occurrences;
1473 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1476 const char **string_index)
1478 struct zebSUInfoB *zsui;
1485 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1488 if (zsui->info.which == ZEB_SU_STR)
1490 *string_index = zsui->info.u.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 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1526 oe.proto = PROTO_Z3950;
1527 oe.oclass = CLASS_ATTSET;
1528 oe.value = (enum oid_value) set;
1530 if (oid_ent_to_oid (&oe, oid))
1532 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1533 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1534 accessInfo->attributeSetIds, oid);
1538 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1539 zinfo_index_category_t cat,
1542 struct zebSUInfoB *zsui;
1544 assert (zei->curDatabaseInfo);
1545 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1546 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1547 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1548 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1550 zsui->info.index_type = index_type;
1551 zsui->info.cat = cat;
1552 zsui->info.doc_occurrences = 0;
1553 zsui->info.term_occurrences = 0;
1554 zsui->info.ordinal = (zei->ordinalSU)++;
1558 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1559 zinfo_index_category_t cat,
1561 const char *index_name)
1563 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1565 zsui->info.which = ZEB_SU_STR;
1566 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1567 return zsui->info.ordinal;
1570 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1572 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1573 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1574 accessInfo->schemas, oid);
1577 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1579 assert (zei->curDatabaseInfo);
1583 zei->curDatabaseInfo->recordBytes += adjust_num;
1584 zei->curDatabaseInfo->dirty = 1;
1588 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1590 assert (zei->curDatabaseInfo);
1594 zei->curDatabaseInfo->recordCount += adjust_num;
1595 zei->curDatabaseInfo->dirty = 1;
1599 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1605 return zei->runNumber += adjust_num;
1608 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1610 RecordAttr *recordAttr;
1612 if (rec->info[recInfo_attr])
1613 return (RecordAttr *) rec->info[recInfo_attr];
1614 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1615 rec->info[recInfo_attr] = (char *) recordAttr;
1616 rec->size[recInfo_attr] = sizeof(*recordAttr);
1618 recordAttr->recordSize = 0;
1619 recordAttr->recordOffset = 0;
1620 recordAttr->runNumber = zei->runNumber;
1621 recordAttr->staticrank = 0;
1625 static void att_loadset(void *p, const char *n, const char *name)
1627 data1_handle dh = (data1_handle) p;
1628 if (!data1_get_attset (dh, name))
1629 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1632 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1634 if (!zei->curDatabaseInfo)
1636 return zei->curDatabaseInfo->ordinalDatabase;
1639 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1641 res_trav(res, "attset", dh, att_loadset);
1645 zebraExplain_addSU adds to AttributeDetails for a database and
1646 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1647 exist for the database.
1649 If the database doesn't exist globally (in TargetInfo) an
1650 AttributeSetInfo must be added (globally).
1655 * indent-tabs-mode: nil
1657 * vim: shiftwidth=4 tabstop=8 expandtab