1 /* $Id: zinfo.c,v 1.77 2007-02-24 16:47:16 adam Exp $
2 Copyright (C) 1995-2007
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sys/types.h>
29 #include <idzebra/version.h>
36 zinfo_index_category_t cat;
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,
414 yaz_log(YLOG_FATAL, "Node node_tgtinfo missing");
415 nmem_destroy(zei->nmem);
418 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
421 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
425 yaz_log(YLOG_FATAL, "Node node_zebra missing");
426 nmem_destroy(zei->nmem);
432 node_list = data1_search_tag(zei->dh, node_zebra->child,
435 np = node_list->child;
437 for(; np; np = np->next)
439 data1_node *node_name = NULL;
440 data1_node *node_id = NULL;
441 data1_node *node_aid = NULL;
443 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
445 for(np2 = np->child; np2; np2 = np2->next)
447 if (np2->which != DATA1N_tag)
449 if (!strcmp(np2->u.tag.tag, "name"))
450 node_name = np2->child;
451 else if (!strcmp(np2->u.tag.tag, "id"))
452 node_id = np2->child;
453 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
454 node_aid = np2->child;
456 assert(node_id && node_name && node_aid);
458 *zdip =(struct zebDatabaseInfoB *)
459 nmem_malloc(zei->nmem, sizeof(**zdip));
460 (*zdip)->readFlag = 1;
462 (*zdip)->data1_database = NULL;
463 (*zdip)->recordCount = 0;
464 (*zdip)->recordBytes = 0;
465 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
467 (*zdip)->databaseName = (char *)
468 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
469 memcpy((*zdip)->databaseName, node_name->u.data.data,
470 node_name->u.data.len);
471 (*zdip)->databaseName[node_name->u.data.len] = '\0';
472 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
473 node_id->u.data.len);
474 (*zdip)->attributeDetails = (zebAttributeDetails)
475 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
476 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
477 node_aid->u.data.len);
478 (*zdip)->attributeDetails->readFlag = 1;
479 (*zdip)->attributeDetails->dirty = 0;
480 (*zdip)->attributeDetails->SUInfo = NULL;
482 zdip = &(*zdip)->next;
486 np = data1_search_tag(zei->dh, node_zebra->child,
489 assert (np && np->which == DATA1N_data);
490 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
492 np = data1_search_tag(zei->dh, node_zebra->child,
495 assert (np && np->which == DATA1N_data);
496 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
498 np = data1_search_tag(zei->dh, node_zebra->child,
501 assert (np && np->which == DATA1N_data);
502 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
503 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
508 else /* create initial targetInfo */
510 data1_node *node_tgtinfo;
519 data1_read_sgml(zei->dh, zei->nmem,
520 "<explain><targetInfo>TargetInfo\n"
522 "<namedResultSets>1</>\n"
523 "<multipleDBSearch>1</>\n"
524 "<nicknames><name>Zebra</></>\n"
526 if (!zei->data1_target)
528 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
529 nmem_destroy(zei->nmem);
532 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
534 assert(node_tgtinfo);
536 zebraExplain_initCommonInfo(zei, node_tgtinfo);
537 zebraExplain_initAccessInfo(zei, node_tgtinfo);
539 /* write now because we want to be sure about the sysno */
540 trec = rec_new(records);
543 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
544 nmem_destroy(zei->nmem);
547 trec->info[recInfo_fileType] =
548 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
549 trec->info[recInfo_databaseName] =
550 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
552 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
553 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
554 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
555 trec->size[recInfo_storeData] = sgml_len;
557 rec_put(records, &trec);
561 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
563 if (!zei->categoryList->dirty)
565 struct zebraCategoryListInfo *zcl = zei->categoryList;
569 zcl->data1_categoryList =
570 data1_read_sgml(zei->dh, zei->nmem,
571 "<explain><categoryList>CategoryList\n"
574 if (zcl->data1_categoryList)
576 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
579 zebraExplain_initCommonInfo(zei, node_cl);
586 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
587 zebAttributeDetails zad)
590 struct zebSUInfoB **zsuip = &zad->SUInfo;
591 data1_node *node_adinfo, *node_zebra, *node_list, *np;
594 rec = rec_get(zei->records, zad->sysno);
596 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
598 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
599 "/attributeDetails");
600 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
602 node_list = data1_search_tag(zei->dh, node_zebra->child,
604 for (np = node_list->child; np; np = np->next)
606 data1_node *node_str = NULL;
607 data1_node *node_ordinal = NULL;
608 data1_node *node_type = NULL;
609 data1_node *node_cat = NULL;
610 data1_node *node_doc_occurrences = NULL;
611 data1_node *node_term_occurrences = NULL;
614 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
616 for (np2 = np->child; np2; np2 = np2->next)
618 if (np2->which != DATA1N_tag || !np2->child ||
619 np2->child->which != DATA1N_data)
621 if (!strcmp(np2->u.tag.tag, "str"))
622 node_str = np2->child;
623 else if (!strcmp(np2->u.tag.tag, "ordinal"))
624 node_ordinal = np2->child;
625 else if (!strcmp(np2->u.tag.tag, "type"))
626 node_type = np2->child;
627 else if (!strcmp(np2->u.tag.tag, "cat"))
628 node_cat = np2->child;
629 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
630 node_doc_occurrences = np2->child;
631 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
632 node_term_occurrences = np2->child;
635 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
639 assert(node_ordinal);
641 *zsuip = (struct zebSUInfoB *)
642 nmem_malloc(zei->nmem, sizeof(**zsuip));
644 if (node_type && node_type->u.data.len > 0)
645 (*zsuip)->info.index_type = node_type->u.data.data[0];
648 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
649 (*zsuip)->info.index_type = 'w';
651 if (node_cat && node_cat->u.data.len > 0)
653 zinfo_index_category_t cat;
655 data1_node *np = node_cat;
656 if (!strncmp(np->u.data.data, "index", np->u.data.len))
657 cat = zinfo_index_category_index;
658 else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
659 cat = zinfo_index_category_sort;
660 else if (!strncmp(np->u.data.data, "alwaysmatches",
662 cat = zinfo_index_category_alwaysmatches;
663 else if (!strncmp(np->u.data.data, "anchor",
665 cat = zinfo_index_category_anchor;
668 yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
669 np->u.data.len, np->u.data.data);
670 cat = zinfo_index_category_index;
672 (*zsuip)->info.cat = cat;
675 (*zsuip)->info.cat = zinfo_index_category_index;
677 if (node_doc_occurrences)
679 data1_node *np = node_doc_occurrences;
680 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
683 if (node_term_occurrences)
685 data1_node *np = node_term_occurrences;
686 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
691 (*zsuip)->info.which = ZEB_SU_STR;
693 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
694 node_str->u.data.data,
695 node_str->u.data.len);
699 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
702 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
703 node_ordinal->u.data.len);
704 zsuip = &(*zsuip)->next;
711 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
712 struct zebDatabaseInfoB *zdi)
715 data1_node *node_dbinfo, *node_zebra, *np;
718 rec = rec_get (zei->records, zdi->sysno);
720 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
722 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
724 assert (node_dbinfo);
725 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
727 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
730 && (np = data1_search_tag (zei->dh, node_zebra->child,
732 && np->child && np->child->which == DATA1N_data)
733 zdi->recordBytes = atoi_zn (np->child->u.data.data,
734 np->child->u.data.len);
737 && (np = data1_search_tag (zei->dh, node_zebra->child,
739 && np->child && np->child->which == DATA1N_data)
740 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
741 np->child->u.data.len);
743 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
745 (np = data1_search_tag (zei->dh, np->child,
746 "recordCountActual")) &&
747 np->child->which == DATA1N_data)
749 zdi->recordCount = atoi_zn (np->child->u.data.data,
750 np->child->u.data.len);
756 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
758 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
762 if (*zdip == zei->curDatabaseInfo)
764 struct zebDatabaseInfoB *zdi = *zdip;
768 zei->updateHandle = update_handle;
770 if (zdi->attributeDetails)
772 /* remove attribute details keys and delete it */
773 zebAttributeDetails zad = zdi->attributeDetails;
775 rec = rec_get(zei->records, zad->sysno);
776 (*zei->updateFunc)(zei->updateHandle, rec, 0);
779 /* remove database record keys and delete it */
780 rec = rec_get (zei->records, zdi->sysno);
781 (*zei->updateFunc)(zei->updateHandle, rec, 0);
784 /* remove from list */
787 /* current database is IR-Explain-1 */
790 zdip = &(*zdip)->next;
795 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
797 struct zebDatabaseInfoB *zdi;
798 const char *database_n = strrchr (database, '/');
803 database_n = database;
806 if (zei->curDatabaseInfo &&
807 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
809 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
811 if (!STRCASECMP (zdi->databaseName, database_n))
817 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
822 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
824 zebraExplain_readDatabase (zei, zdi);
826 if (zdi->attributeDetails->readFlag)
829 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
831 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
833 zei->curDatabaseInfo = zdi;
837 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
839 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
840 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
841 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
842 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
845 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
847 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
849 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
853 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
855 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
856 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
857 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
860 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
861 zebAccessInfo accessInfo)
863 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
869 data1_pr_tree (zei->dh, n, stdout);
870 zebra_exit("zebraExplain_updateAccessInfo");
873 if ((p = accessInfo->attributeSetIds))
875 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
876 for (; p; p = p->next)
877 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
879 if ((p = accessInfo->schemas))
881 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
882 for (; p; p = p->next)
883 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
887 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
888 int explain_database)
890 struct zebDatabaseInfoB *zdi;
891 data1_node *node_dbinfo, *node_adinfo;
892 const char *database_n = strrchr (database, '/');
897 database_n = database;
900 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
903 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
905 if (!STRCASECMP (zdi->databaseName, database_n))
910 /* it's new really. make it */
911 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
912 zdi->next = zei->databaseInfo;
913 zei->databaseInfo = zdi;
915 zdi->recordCount = 0;
916 zdi->recordBytes = 0;
918 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
920 zdi->ordinalDatabase = zei->ordinalDatabase++;
922 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
927 zdi->data1_database =
928 data1_read_sgml (zei->dh, zei->nmem,
929 "<explain><databaseInfo>DatabaseInfo\n"
931 if (!zdi->data1_database)
934 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
936 assert (node_dbinfo);
938 zebraExplain_initCommonInfo (zei, node_dbinfo);
939 zebraExplain_initAccessInfo (zei, node_dbinfo);
941 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
942 database, zei->nmem);
944 if (explain_database)
945 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
948 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
951 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
955 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
959 zei->curDatabaseInfo = zdi;
961 zdi->attributeDetails = (zebAttributeDetails)
962 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
963 zdi->attributeDetails->readFlag = 0;
964 zdi->attributeDetails->sysno = 0;
965 zdi->attributeDetails->dirty = 1;
966 zdi->attributeDetails->SUInfo = NULL;
967 zdi->attributeDetails->data1_tree =
968 data1_read_sgml (zei->dh, zei->nmem,
969 "<explain><attributeDetails>AttributeDetails\n"
972 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
973 "/attributeDetails");
974 assert (node_adinfo);
976 zebraExplain_initCommonInfo (zei, node_adinfo);
978 data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
984 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
985 struct zebraCategoryListInfo *zcl,
992 data1_node *node_ci, *node_categoryList;
994 static char *category[] = {
1006 node_categoryList = zcl->data1_categoryList;
1009 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
1012 drec = createRecord (zei->records, &sysno);
1016 node_ci = data1_search_tag (zei->dh, node_categoryList,
1019 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
1023 for (i = 0; category[i]; i++)
1025 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
1026 0 /* attr */, node_ci);
1028 data1_mk_tag_data_text (zei->dh, node_cat, "name",
1029 category[i], zei->nmem);
1031 /* extract *searchable* keys from it. We do this here, because
1032 record count, etc. is affected */
1034 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1036 /* convert to "SGML" and write it */
1038 data1_pr_tree (zei->dh, node_categoryList, stderr);
1040 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1041 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1042 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1043 drec->size[recInfo_storeData] = sgml_len;
1045 rec_put (zei->records, &drec);
1048 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1049 zebAttributeDetails zad,
1050 const char *databaseName,
1056 data1_node *node_adinfo, *node_list, *node_zebra;
1057 struct zebSUInfoB *zsui;
1064 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1065 data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1068 drec = createRecord (zei->records, &zad->sysno);
1071 assert (zad->data1_tree);
1073 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1074 "/attributeDetails");
1075 zebraExplain_updateCommonInfo (zei, node_adinfo);
1077 /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
1078 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1079 "zebraInfo", node_adinfo);
1081 /* extract *searchable* keys from it. We do this here, because
1082 record count, etc. is affected */
1084 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1085 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1086 "attrlist", node_zebra);
1087 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1089 data1_node *node_attr;
1090 char index_type_str[2];
1092 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1095 index_type_str[0] = zsui->info.index_type;
1096 index_type_str[1] = '\0';
1097 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1098 index_type_str, zei->nmem);
1099 if (zsui->info.which == ZEB_SU_STR)
1101 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1102 zsui->info.u.str, zei->nmem);
1104 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1105 zsui->info.ordinal, zei->nmem);
1107 data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
1108 zsui->info.doc_occurrences, zei->nmem);
1109 data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
1110 zsui->info.term_occurrences, zei->nmem);
1111 switch(zsui->info.cat)
1113 case zinfo_index_category_index:
1114 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1115 "index", zei->nmem); break;
1116 case zinfo_index_category_sort:
1117 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1118 "sort", zei->nmem); break;
1119 case zinfo_index_category_alwaysmatches:
1120 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1121 "alwaysmatches", zei->nmem); break;
1122 case zinfo_index_category_anchor:
1123 data1_mk_tag_data_text (zei->dh, node_attr, "cat",
1124 "anchor", zei->nmem); break;
1127 /* convert to "SGML" and write it */
1129 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1131 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1133 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1134 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1135 drec->size[recInfo_storeData] = sgml_len;
1137 rec_put (zei->records, &drec);
1140 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1141 struct zebDatabaseInfoB *zdi,
1147 data1_node *node_dbinfo, *node_count, *node_zebra;
1154 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1156 drec = createRecord (zei->records, &zdi->sysno);
1159 assert (zdi->data1_database);
1161 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1164 assert (node_dbinfo);
1165 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1166 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1169 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1170 "recordCount", node_dbinfo);
1171 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1172 zdi->recordCount, zei->nmem);
1174 /* zebra info (private) */
1175 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1176 "zebraInfo", node_dbinfo);
1178 /* extract *searchable* keys from it. We do this here, because
1179 record count, etc. is affected */
1181 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1182 data1_mk_tag_data_zint (zei->dh, node_zebra,
1183 "recordBytes", zdi->recordBytes, zei->nmem);
1185 data1_mk_tag_data_zint(zei->dh, node_zebra,
1186 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1188 /* convert to "SGML" and write it */
1190 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1192 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1194 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1195 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1196 drec->size[recInfo_storeData] = sgml_len;
1198 rec_put (zei->records, &drec);
1201 static void writeAttributeValues (ZebraExplainInfo zei,
1202 data1_node *node_values,
1203 data1_attset *attset)
1206 data1_attset_child *c;
1211 for (c = attset->children; c; c = c->next)
1212 writeAttributeValues (zei, node_values, c->child);
1213 for (atts = attset->atts; atts; atts = atts->next)
1215 data1_node *node_value;
1217 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1218 0 /* attr */, node_values);
1219 data1_mk_tag_data_text (zei->dh, node_value, "name",
1220 atts->name, zei->nmem);
1221 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1222 0 /* attr */, node_value);
1223 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1224 atts->value, zei->nmem);
1229 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1236 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1237 data1_node *node_values;
1238 struct oident *entp;
1239 struct data1_attset *attset = NULL;
1241 if ((entp = oid_getentbyoid (o->oid)))
1242 attset = data1_attset_search_id (zei->dh, entp->value);
1245 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1246 attset ? attset->name : "<unknown>");
1249 drec = createRecord (zei->records, &o->sysno);
1253 data1_read_sgml (zei->dh, zei->nmem,
1254 "<explain><attributeSetInfo>AttributeSetInfo\n"
1257 node_attinfo = data1_search_tag (zei->dh, node_root,
1258 "/attributeSetInfo");
1260 assert (node_attinfo);
1261 zebraExplain_initCommonInfo (zei, node_attinfo);
1262 zebraExplain_updateCommonInfo (zei, node_attinfo);
1264 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1265 "oid", o->oid, zei->nmem);
1266 if (attset && attset->name)
1267 data1_mk_tag_data_text (zei->dh, node_attinfo,
1268 "name", attset->name, zei->nmem);
1270 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1271 "attributes", node_attinfo);
1272 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1273 "attributeType", node_attributes);
1274 data1_mk_tag_data_text (zei->dh, node_atttype,
1275 "name", "Use", zei->nmem);
1276 data1_mk_tag_data_text (zei->dh, node_atttype,
1277 "description", "Use Attribute", zei->nmem);
1278 data1_mk_tag_data_int (zei->dh, node_atttype,
1279 "type", 1, zei->nmem);
1280 node_values = data1_mk_tag (zei->dh, zei->nmem,
1281 "attributeValues", 0 /* attr */, node_atttype);
1283 writeAttributeValues (zei, node_values, attset);
1285 /* extract *searchable* keys from it. We do this here, because
1286 record count, etc. is affected */
1288 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1289 /* convert to "SGML" and write it */
1291 data1_pr_tree (zei->dh, node_root, stderr);
1293 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1294 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1295 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1296 drec->size[recInfo_storeData] = sgml_len;
1298 rec_put (zei->records, &drec);
1301 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1303 struct zebDatabaseInfoB *zdi;
1304 data1_node *node_tgtinfo, *node_list, *node_zebra;
1313 trec = rec_get_root(zei->records);
1314 xfree (trec->info[recInfo_storeData]);
1316 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1318 assert (node_tgtinfo);
1320 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1321 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1323 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1324 "zebraInfo", node_tgtinfo);
1325 /* convert to "SGML" and write it */
1327 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1329 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1330 ZEBRAVER, zei->nmem);
1331 node_list = data1_mk_tag (zei->dh, zei->nmem,
1332 "databaseList", 0 /* attr */, node_zebra);
1333 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1335 data1_node *node_db;
1336 node_db = data1_mk_tag (zei->dh, zei->nmem,
1337 "database", 0 /* attr */, node_list);
1338 data1_mk_tag_data_text (zei->dh, node_db, "name",
1339 zdi->databaseName, zei->nmem);
1340 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1341 zdi->sysno, zei->nmem);
1342 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1343 zdi->attributeDetails->sysno, zei->nmem);
1345 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1346 zei->ordinalSU, zei->nmem);
1348 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
1349 zei->ordinalDatabase, zei->nmem);
1351 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1352 zei->runNumber, zei->nmem);
1355 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1357 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1359 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1360 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1361 trec->size[recInfo_storeData] = sgml_len;
1363 rec_put (zei->records, &trec);
1366 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
1367 zinfo_index_category_t cat,
1371 struct zebSUInfoB **zsui;
1373 assert (zei->curDatabaseInfo);
1374 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1375 *zsui; zsui = &(*zsui)->next)
1376 if ( (index_type == -1 || (*zsui)->info.index_type == index_type)
1377 && (*zsui)->info.cat == cat
1378 && (*zsui)->info.which == ZEB_SU_STR
1379 && !yaz_matchstr((*zsui)->info.u.str, str))
1381 struct zebSUInfoB *zsui_this = *zsui;
1383 /* take it out of the list and move to front */
1384 *zsui = (*zsui)->next;
1385 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1386 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1388 return zsui_this->info.ordinal;
1393 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1394 int (*f)(void *handle, int ord))
1396 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1399 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1400 for ( ;zsui; zsui = zsui->next)
1401 (*f)(handle, zsui->info.ordinal);
1407 struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
1411 struct zebDatabaseInfoB *zdb;
1413 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1415 struct zebSUInfoB **zsui;
1417 if (zdb->attributeDetails->readFlag)
1418 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1420 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1421 zsui = &(*zsui)->next)
1422 if ((*zsui)->info.ordinal == ord)
1424 struct zebSUInfoB *zsui_this = *zsui;
1426 /* take it out of the list and move to front */
1427 *zsui = (*zsui)->next;
1428 zsui_this->next = zdb->attributeDetails->SUInfo;
1429 zdb->attributeDetails->SUInfo = zsui_this;
1432 zdb->attributeDetails->dirty = 1;
1434 *db = zdb->databaseName;
1443 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1444 int term_delta, int doc_delta)
1446 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1449 zsui->info.term_occurrences += term_delta;
1450 zsui->info.doc_occurrences += doc_delta;
1456 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1457 zint *term_occurrences,
1458 zint *doc_occurrences)
1460 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1463 *term_occurrences = zsui->info.term_occurrences;
1464 *doc_occurrences = zsui->info.doc_occurrences;
1470 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1472 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1474 return zsui->info.doc_occurrences;
1478 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1480 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1482 return zsui->info.term_occurrences;
1486 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1489 const char **string_index)
1491 struct zebSUInfoB *zsui;
1498 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1501 if (zsui->info.which == ZEB_SU_STR)
1503 *string_index = zsui->info.u.str;
1505 *index_type = zsui->info.index_type;
1513 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1514 zebAccessObject *op,
1519 for (ao = *op; ao; ao = ao->next)
1520 if (!oid_oidcmp (oid, ao->oid))
1524 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1527 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1534 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1539 oe.proto = PROTO_Z3950;
1540 oe.oclass = CLASS_ATTSET;
1541 oe.value = (enum oid_value) set;
1543 if (oid_ent_to_oid (&oe, oid))
1545 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1546 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1547 accessInfo->attributeSetIds, oid);
1551 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1552 zinfo_index_category_t cat,
1555 struct zebSUInfoB *zsui;
1557 assert (zei->curDatabaseInfo);
1558 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1559 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1560 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1561 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1563 zsui->info.index_type = index_type;
1564 zsui->info.cat = cat;
1565 zsui->info.doc_occurrences = 0;
1566 zsui->info.term_occurrences = 0;
1567 zsui->info.ordinal = (zei->ordinalSU)++;
1571 int zebraExplain_add_attr_str(ZebraExplainInfo zei,
1572 zinfo_index_category_t cat,
1574 const char *index_name)
1576 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1578 zsui->info.which = ZEB_SU_STR;
1579 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1580 return zsui->info.ordinal;
1583 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1585 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1586 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1587 accessInfo->schemas, oid);
1590 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1592 assert (zei->curDatabaseInfo);
1596 zei->curDatabaseInfo->recordBytes += adjust_num;
1597 zei->curDatabaseInfo->dirty = 1;
1601 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1603 assert (zei->curDatabaseInfo);
1607 zei->curDatabaseInfo->recordCount += adjust_num;
1608 zei->curDatabaseInfo->dirty = 1;
1612 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1618 return zei->runNumber += adjust_num;
1621 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1623 RecordAttr *recordAttr;
1625 if (rec->info[recInfo_attr])
1626 return (RecordAttr *) rec->info[recInfo_attr];
1627 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1629 memset(recordAttr, '\0', sizeof(*recordAttr));
1630 rec->info[recInfo_attr] = (char *) recordAttr;
1631 rec->size[recInfo_attr] = sizeof(*recordAttr);
1633 recordAttr->recordSize = 0;
1634 recordAttr->recordOffset = 0;
1635 recordAttr->runNumber = zei->runNumber;
1636 recordAttr->staticrank = 0;
1640 static void att_loadset(void *p, const char *n, const char *name)
1642 data1_handle dh = (data1_handle) p;
1643 if (!data1_get_attset (dh, name))
1644 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1647 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1649 if (!zei->curDatabaseInfo)
1651 return zei->curDatabaseInfo->ordinalDatabase;
1654 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1656 res_trav(res, "attset", dh, att_loadset);
1660 zebraExplain_addSU adds to AttributeDetails for a database and
1661 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1662 exist for the database.
1664 If the database doesn't exist globally (in TargetInfo) an
1665 AttributeSetInfo must be added (globally).
1670 * indent-tabs-mode: nil
1672 * vim: shiftwidth=4 tabstop=8 expandtab