1 /* $Id: zinfo.c,v 1.75 2006-11-27 10:40:33 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 zint sysno; /* sysno of database info */
83 int readFlag; /* 1: read is needed when referenced; 0 if not */
84 int dirty; /* 1: database is dirty: write is needed */
85 struct zebDatabaseInfoB *next;
86 zebAccessInfo accessInfo;
89 struct zebraExplainAttset {
92 struct zebraExplainAttset *next;
95 struct zebraCategoryListInfo {
98 data1_node *data1_categoryList;
101 struct zebraExplainInfo {
110 struct zebraExplainAttset *attsets;
112 data1_node *data1_target;
113 struct zebraCategoryListInfo *categoryList;
114 struct zebDatabaseInfoB *databaseInfo;
115 struct zebDatabaseInfoB *curDatabaseInfo;
116 zebAccessInfo accessInfo;
117 char date[15]; /* YYYY MMDD HH MM SS */
118 ZebraExplainUpdateFunc *updateFunc;
122 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
123 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
125 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
127 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
130 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
131 struct zebDatabaseInfoB *zdi,
133 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
134 zebAttributeDetails zad,
135 const char *databaseName,
137 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
138 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
141 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
142 struct zebraCategoryListInfo *zcl,
146 static Record createRecord(Records records, zint *sysno)
151 rec = rec_get(records, *sysno);
154 xfree(rec->info[recInfo_storeData]);
158 rec = rec_new(records);
163 rec->info[recInfo_fileType] =
164 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
165 rec->info[recInfo_databaseName] =
166 rec_strdup("IR-Explain-1",
167 &rec->size[recInfo_databaseName]);
172 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
176 zei->updateHandle = handle;
179 struct zebDatabaseInfoB *zdi;
182 /* write each database info record */
183 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
185 zebraExplain_writeDatabase(zei, zdi, 1);
186 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
187 zdi->databaseName, 1);
189 zebraExplain_writeTarget(zei, 1);
190 zebraExplain_writeCategoryList(zei,
193 assert(zei->accessInfo);
194 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
196 zebraExplain_writeAttributeSet(zei, o, 1);
197 for (o = zei->accessInfo->schemas; o; o = o->next)
200 /* zebraExplain_writeSchema(zei, o, 1); */
203 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
205 zebraExplain_writeDatabase(zei, zdi, 0);
206 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
207 zdi->databaseName, 0);
209 zebraExplain_writeTarget(zei, 0);
213 void zebraExplain_close(ZebraExplainInfo zei)
216 yaz_log(YLOG_LOG, "zebraExplain_close");
220 zebraExplain_flush(zei, zei->updateHandle);
221 nmem_destroy(zei->nmem);
224 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
229 for (np = n->child; np; np = np->next)
236 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
238 len = np->child->u.data.len;
241 memcpy(str, np->child->u.data.data, len);
244 oid = odr_getoidbystr_nmem(zei->nmem, str);
246 for (ao = *op; ao; ao = ao->next)
247 if (!oid_oidcmp(oid, ao->oid))
254 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
264 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
265 zebAccessInfo *accessInfo)
271 *accessInfo = (zebAccessInfo)
272 nmem_malloc(zei->nmem, sizeof(**accessInfo));
273 (*accessInfo)->attributeSetIds = 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);
858 zebra_exit("zebraExplain_updateAccessInfo");
861 if ((p = accessInfo->attributeSetIds))
863 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
864 for (; p; p = p->next)
865 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
867 if ((p = accessInfo->schemas))
869 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
870 for (; p; p = p->next)
871 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
875 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
876 int explain_database)
878 struct zebDatabaseInfoB *zdi;
879 data1_node *node_dbinfo, *node_adinfo;
880 const char *database_n = strrchr (database, '/');
885 database_n = database;
888 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
891 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
893 if (!STRCASECMP (zdi->databaseName, database_n))
898 /* it's new really. make it */
899 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
900 zdi->next = zei->databaseInfo;
901 zei->databaseInfo = zdi;
903 zdi->recordCount = 0;
904 zdi->recordBytes = 0;
906 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
908 zdi->ordinalDatabase = zei->ordinalDatabase++;
910 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
915 zdi->data1_database =
916 data1_read_sgml (zei->dh, zei->nmem,
917 "<explain><databaseInfo>DatabaseInfo\n"
919 if (!zdi->data1_database)
922 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
924 assert (node_dbinfo);
926 zebraExplain_initCommonInfo (zei, node_dbinfo);
927 zebraExplain_initAccessInfo (zei, node_dbinfo);
929 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
930 database, zei->nmem);
932 if (explain_database)
933 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
936 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
939 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
943 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
947 zei->curDatabaseInfo = zdi;
949 zdi->attributeDetails = (zebAttributeDetails)
950 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
951 zdi->attributeDetails->readFlag = 0;
952 zdi->attributeDetails->sysno = 0;
953 zdi->attributeDetails->dirty = 1;
954 zdi->attributeDetails->SUInfo = NULL;
955 zdi->attributeDetails->data1_tree =
956 data1_read_sgml (zei->dh, zei->nmem,
957 "<explain><attributeDetails>AttributeDetails\n"
960 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
961 "/attributeDetails");
962 assert (node_adinfo);
964 zebraExplain_initCommonInfo (zei, node_adinfo);
966 data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
972 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
973 struct zebraCategoryListInfo *zcl,
980 data1_node *node_ci, *node_categoryList;
982 static char *category[] = {
994 node_categoryList = zcl->data1_categoryList;
997 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
1000 drec = createRecord (zei->records, &sysno);
1004 node_ci = data1_search_tag (zei->dh, node_categoryList,
1007 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
1011 for (i = 0; category[i]; i++)
1013 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
1014 0 /* attr */, node_ci);
1016 data1_mk_tag_data_text (zei->dh, node_cat, "name",
1017 category[i], zei->nmem);
1019 /* extract *searchable* keys from it. We do this here, because
1020 record count, etc. is affected */
1022 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1024 /* convert to "SGML" and write it */
1026 data1_pr_tree (zei->dh, node_categoryList, stderr);
1028 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1029 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1030 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1031 drec->size[recInfo_storeData] = sgml_len;
1033 rec_put (zei->records, &drec);
1036 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1037 zebAttributeDetails zad,
1038 const char *databaseName,
1044 data1_node *node_adinfo, *node_list, *node_zebra;
1045 struct zebSUInfoB *zsui;
1052 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1053 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1056 drec = createRecord (zei->records, &zad->sysno);
1059 assert (zad->data1_tree);
1061 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1062 "/attributeDetails");
1063 zebraExplain_updateCommonInfo (zei, node_adinfo);
1065 /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
1066 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1067 "zebraInfo", node_adinfo);
1069 /* extract *searchable* keys from it. We do this here, because
1070 record count, etc. is affected */
1072 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
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);
1157 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1158 "recordCount", node_dbinfo);
1159 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1160 zdi->recordCount, zei->nmem);
1162 /* zebra info (private) */
1163 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1164 "zebraInfo", node_dbinfo);
1166 /* extract *searchable* keys from it. We do this here, because
1167 record count, etc. is affected */
1169 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1170 data1_mk_tag_data_zint (zei->dh, node_zebra,
1171 "recordBytes", zdi->recordBytes, zei->nmem);
1173 data1_mk_tag_data_zint(zei->dh, node_zebra,
1174 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1176 /* convert to "SGML" and write it */
1178 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1180 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1182 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1183 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1184 drec->size[recInfo_storeData] = sgml_len;
1186 rec_put (zei->records, &drec);
1189 static void writeAttributeValues (ZebraExplainInfo zei,
1190 data1_node *node_values,
1191 data1_attset *attset)
1194 data1_attset_child *c;
1199 for (c = attset->children; c; c = c->next)
1200 writeAttributeValues (zei, node_values, c->child);
1201 for (atts = attset->atts; atts; atts = atts->next)
1203 data1_node *node_value;
1205 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1206 0 /* attr */, node_values);
1207 data1_mk_tag_data_text (zei->dh, node_value, "name",
1208 atts->name, zei->nmem);
1209 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1210 0 /* attr */, node_value);
1211 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1212 atts->value, zei->nmem);
1217 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1224 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1225 data1_node *node_values;
1226 struct oident *entp;
1227 struct data1_attset *attset = NULL;
1229 if ((entp = oid_getentbyoid (o->oid)))
1230 attset = data1_attset_search_id (zei->dh, entp->value);
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,
1359 struct zebSUInfoB **zsui;
1361 assert (zei->curDatabaseInfo);
1362 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1363 *zsui; zsui = &(*zsui)->next)
1364 if ( (index_type == -1 || (*zsui)->info.index_type == index_type)
1365 && (*zsui)->info.cat == cat
1366 && (*zsui)->info.which == ZEB_SU_STR
1367 && !yaz_matchstr((*zsui)->info.u.str, str))
1369 struct zebSUInfoB *zsui_this = *zsui;
1371 /* take it out of the list and move to front */
1372 *zsui = (*zsui)->next;
1373 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1374 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1376 return zsui_this->info.ordinal;
1381 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1382 int (*f)(void *handle, int ord))
1384 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1387 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1388 for ( ;zsui; zsui = zsui->next)
1389 (*f)(handle, zsui->info.ordinal);
1395 struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
1399 struct zebDatabaseInfoB *zdb;
1401 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1403 struct zebSUInfoB **zsui;
1405 if (zdb->attributeDetails->readFlag)
1406 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1408 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1409 zsui = &(*zsui)->next)
1410 if ((*zsui)->info.ordinal == ord)
1412 struct zebSUInfoB *zsui_this = *zsui;
1414 /* take it out of the list and move to front */
1415 *zsui = (*zsui)->next;
1416 zsui_this->next = zdb->attributeDetails->SUInfo;
1417 zdb->attributeDetails->SUInfo = zsui_this;
1420 zdb->attributeDetails->dirty = 1;
1422 *db = zdb->databaseName;
1431 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1432 int term_delta, int doc_delta)
1434 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1437 zsui->info.term_occurrences += term_delta;
1438 zsui->info.doc_occurrences += doc_delta;
1444 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1445 zint *term_occurrences,
1446 zint *doc_occurrences)
1448 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1451 *term_occurrences = zsui->info.term_occurrences;
1452 *doc_occurrences = zsui->info.doc_occurrences;
1458 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1460 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1462 return zsui->info.doc_occurrences;
1466 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1468 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1470 return zsui->info.term_occurrences;
1474 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1477 const char **string_index)
1479 struct zebSUInfoB *zsui;
1486 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1489 if (zsui->info.which == ZEB_SU_STR)
1491 *string_index = zsui->info.u.str;
1493 *index_type = zsui->info.index_type;
1501 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1502 zebAccessObject *op,
1507 for (ao = *op; ao; ao = ao->next)
1508 if (!oid_oidcmp (oid, ao->oid))
1512 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1515 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1522 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1527 oe.proto = PROTO_Z3950;
1528 oe.oclass = CLASS_ATTSET;
1529 oe.value = (enum oid_value) set;
1531 if (oid_ent_to_oid (&oe, oid))
1533 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1534 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1535 accessInfo->attributeSetIds, oid);
1539 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1540 zinfo_index_category_t cat,
1543 struct zebSUInfoB *zsui;
1545 assert (zei->curDatabaseInfo);
1546 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1547 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1548 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1549 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1551 zsui->info.index_type = index_type;
1552 zsui->info.cat = cat;
1553 zsui->info.doc_occurrences = 0;
1554 zsui->info.term_occurrences = 0;
1555 zsui->info.ordinal = (zei->ordinalSU)++;
1559 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1560 zinfo_index_category_t cat,
1562 const char *index_name)
1564 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1566 zsui->info.which = ZEB_SU_STR;
1567 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1568 return zsui->info.ordinal;
1571 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1573 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1574 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1575 accessInfo->schemas, oid);
1578 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1580 assert (zei->curDatabaseInfo);
1584 zei->curDatabaseInfo->recordBytes += adjust_num;
1585 zei->curDatabaseInfo->dirty = 1;
1589 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1591 assert (zei->curDatabaseInfo);
1595 zei->curDatabaseInfo->recordCount += adjust_num;
1596 zei->curDatabaseInfo->dirty = 1;
1600 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1606 return zei->runNumber += adjust_num;
1609 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1611 RecordAttr *recordAttr;
1613 if (rec->info[recInfo_attr])
1614 return (RecordAttr *) rec->info[recInfo_attr];
1615 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1617 memset(recordAttr, '\0', sizeof(*recordAttr));
1618 rec->info[recInfo_attr] = (char *) recordAttr;
1619 rec->size[recInfo_attr] = sizeof(*recordAttr);
1621 recordAttr->recordSize = 0;
1622 recordAttr->recordOffset = 0;
1623 recordAttr->runNumber = zei->runNumber;
1624 recordAttr->staticrank = 0;
1628 static void att_loadset(void *p, const char *n, const char *name)
1630 data1_handle dh = (data1_handle) p;
1631 if (!data1_get_attset (dh, name))
1632 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1635 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1637 if (!zei->curDatabaseInfo)
1639 return zei->curDatabaseInfo->ordinalDatabase;
1642 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1644 res_trav(res, "attset", dh, att_loadset);
1648 zebraExplain_addSU adds to AttributeDetails for a database and
1649 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1650 exist for the database.
1652 If the database doesn't exist globally (in TargetInfo) an
1653 AttributeSetInfo must be added (globally).
1658 * indent-tabs-mode: nil
1660 * vim: shiftwidth=4 tabstop=8 expandtab