1 /* $Id: zinfo.c,v 1.66 2006-06-13 12:02:12 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 Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include <sys/types.h>
29 #include <idzebra/version.h>
36 #define ZEB_SU_SET_USE 1
44 zint term_occurrences;
48 struct zebSUInfo info;
49 struct zebSUInfoB *next;
52 typedef struct zebAccessObjectB *zebAccessObject;
53 struct zebAccessObjectB {
60 typedef struct zebAccessInfoB *zebAccessInfo;
61 struct zebAccessInfoB {
62 zebAccessObject attributeSetIds;
63 zebAccessObject schemas;
67 struct zebSUInfoB *SUInfo;
71 data1_node *data1_tree;
72 } *zebAttributeDetails;
74 struct zebDatabaseInfoB {
75 zebAttributeDetails attributeDetails;
78 data1_node *data1_database;
79 zint recordCount; /* records in db */
80 zint recordBytes; /* size of records */
81 SYSNO sysno; /* sysno of database info */
82 int readFlag; /* 1: read is needed when referenced; 0 if not */
83 int dirty; /* 1: database is dirty: write is needed */
84 struct zebDatabaseInfoB *next;
85 zebAccessInfo accessInfo;
88 struct zebraExplainAttset {
91 struct zebraExplainAttset *next;
94 struct zebraCategoryListInfo {
97 data1_node *data1_categoryList;
100 struct zebraExplainInfo {
109 struct zebraExplainAttset *attsets;
111 data1_node *data1_target;
112 struct zebraCategoryListInfo *categoryList;
113 struct zebDatabaseInfoB *databaseInfo;
114 struct zebDatabaseInfoB *curDatabaseInfo;
115 zebAccessInfo accessInfo;
116 char date[15]; /* YYYY MMDD HH MM SS */
117 ZebraExplainUpdateFunc *updateFunc;
121 static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n);
122 static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n);
124 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
126 return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
129 static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
130 struct zebDatabaseInfoB *zdi,
132 static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
133 zebAttributeDetails zad,
134 const char *databaseName,
136 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
137 static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
140 static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
141 struct zebraCategoryListInfo *zcl,
145 static Record createRecord(Records records, SYSNO *sysno)
150 rec = rec_get(records, *sysno);
153 xfree(rec->info[recInfo_storeData]);
157 rec = rec_new(records);
162 rec->info[recInfo_fileType] =
163 rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
164 rec->info[recInfo_databaseName] =
165 rec_strdup("IR-Explain-1",
166 &rec->size[recInfo_databaseName]);
171 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
175 zei->updateHandle = handle;
178 struct zebDatabaseInfoB *zdi;
181 /* write each database info record */
182 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
184 zebraExplain_writeDatabase(zei, zdi, 1);
185 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
186 zdi->databaseName, 1);
188 zebraExplain_writeTarget(zei, 1);
189 zebraExplain_writeCategoryList(zei,
192 assert(zei->accessInfo);
193 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
195 zebraExplain_writeAttributeSet(zei, o, 1);
196 for (o = zei->accessInfo->schemas; o; o = o->next)
199 /* zebraExplain_writeSchema(zei, o, 1); */
202 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
204 zebraExplain_writeDatabase(zei, zdi, 0);
205 zebraExplain_writeAttributeDetails(zei, zdi->attributeDetails,
206 zdi->databaseName, 0);
208 zebraExplain_writeTarget(zei, 0);
212 void zebraExplain_close(ZebraExplainInfo zei)
215 yaz_log(YLOG_LOG, "zebraExplain_close");
219 zebraExplain_flush(zei, zei->updateHandle);
220 nmem_destroy(zei->nmem);
223 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
228 for (np = n->child; np; np = np->next)
235 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
237 len = np->child->u.data.len;
240 memcpy(str, np->child->u.data.data, len);
243 oid = odr_getoidbystr_nmem(zei->nmem, str);
245 for (ao = *op; ao; ao = ao->next)
246 if (!oid_oidcmp(oid, ao->oid))
253 ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
263 void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
264 zebAccessInfo *accessInfo)
270 *accessInfo = (zebAccessInfo)
271 nmem_malloc(zei->nmem, sizeof(**accessInfo));
272 (*accessInfo)->attributeSetIds = NULL;
273 (*accessInfo)->schemas = NULL;
277 if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
279 if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
280 zebraExplain_mergeOids(zei, np,
281 &(*accessInfo)->attributeSetIds);
282 if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
283 zebraExplain_mergeOids(zei, np,
284 &(*accessInfo)->schemas);
293 databaseList (list of databases)
298 targetInfo: TargetInfo
305 dateAdded: 20030630190601
306 dateChanged: 20030630190601
312 oid: 1.2.840.10003.3.2
313 oid: 1.2.840.10003.3.5
314 oid: 1.2.840.10003.3.1
316 oid: 1.2.840.10003.13.1000.81.2
317 oid: 1.2.840.10003.13.2
324 attributeDetailsId: 51
328 attributeDetailsId: 53
331 nextResultSetPosition = 2
334 ZebraExplainInfo zebraExplain_open(
335 Records records, data1_handle dh,
339 ZebraExplainUpdateFunc *updateFunc)
342 ZebraExplainInfo zei;
343 struct zebDatabaseInfoB **zdip;
346 NMEM nmem = nmem_create();
349 yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
351 zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
352 zei->databaseInfo = 0;
353 zei->write_flag = writeFlag;
354 zei->updateHandle = updateHandle;
355 zei->updateFunc = updateFunc;
357 zei->ordinalDatabase = 1;
358 zei->curDatabaseInfo = NULL;
359 zei->records = records;
363 data1_get_absyn (zei->dh, "explain", DATA1_XPATH_INDEXING_DISABLE);
367 zei->categoryList = (struct zebraCategoryListInfo *)
368 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
369 zei->categoryList->sysno = 0;
370 zei->categoryList->dirty = 0;
371 zei->categoryList->data1_categoryList = NULL;
373 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
376 tm = localtime(&our_time);
377 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
378 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
379 tm->tm_hour, tm->tm_min, tm->tm_sec);
381 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
384 zdip = &zei->databaseInfo;
385 trec = rec_get_root(records); /* get "root" record */
390 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
391 if (trec) /* targetInfo already exists ... */
393 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
395 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
397 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
399 if (!zei->data1_target)
402 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
403 nmem_destroy(zei->nmem);
407 data1_pr_tree(zei->dh, zei->data1_target, stderr);
409 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
411 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
414 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
419 node_list = data1_search_tag(zei->dh, node_zebra->child,
422 np = node_list->child;
424 for(; np; np = np->next)
426 data1_node *node_name = NULL;
427 data1_node *node_id = NULL;
428 data1_node *node_aid = NULL;
430 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
432 for(np2 = np->child; np2; np2 = np2->next)
434 if (np2->which != DATA1N_tag)
436 if (!strcmp(np2->u.tag.tag, "name"))
437 node_name = np2->child;
438 else if (!strcmp(np2->u.tag.tag, "id"))
439 node_id = np2->child;
440 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
441 node_aid = np2->child;
443 assert(node_id && node_name && node_aid);
445 *zdip =(struct zebDatabaseInfoB *)
446 nmem_malloc(zei->nmem, sizeof(**zdip));
447 (*zdip)->readFlag = 1;
449 (*zdip)->data1_database = NULL;
450 (*zdip)->recordCount = 0;
451 (*zdip)->recordBytes = 0;
452 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
454 (*zdip)->databaseName = (char *)
455 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
456 memcpy((*zdip)->databaseName, node_name->u.data.data,
457 node_name->u.data.len);
458 (*zdip)->databaseName[node_name->u.data.len] = '\0';
459 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
460 node_id->u.data.len);
461 (*zdip)->attributeDetails = (zebAttributeDetails)
462 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
463 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
464 node_aid->u.data.len);
465 (*zdip)->attributeDetails->readFlag = 1;
466 (*zdip)->attributeDetails->dirty = 0;
467 (*zdip)->attributeDetails->SUInfo = NULL;
469 zdip = &(*zdip)->next;
473 np = data1_search_tag(zei->dh, node_zebra->child,
476 assert (np && np->which == DATA1N_data);
477 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
479 np = data1_search_tag(zei->dh, node_zebra->child,
482 assert (np && np->which == DATA1N_data);
483 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
485 np = data1_search_tag(zei->dh, node_zebra->child,
488 assert (np && np->which == DATA1N_data);
489 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
490 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
495 else /* create initial targetInfo */
497 data1_node *node_tgtinfo;
506 data1_read_sgml(zei->dh, zei->nmem,
507 "<explain><targetInfo>TargetInfo\n"
509 "<namedResultSets>1</>\n"
510 "<multipleDBSearch>1</>\n"
511 "<nicknames><name>Zebra</></>\n"
513 if (!zei->data1_target)
515 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
516 nmem_destroy(zei->nmem);
519 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
521 assert(node_tgtinfo);
523 zebraExplain_initCommonInfo(zei, node_tgtinfo);
524 zebraExplain_initAccessInfo(zei, node_tgtinfo);
526 /* write now because we want to be sure about the sysno */
527 trec = rec_new(records);
530 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
531 nmem_destroy(zei->nmem);
534 trec->info[recInfo_fileType] =
535 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
536 trec->info[recInfo_databaseName] =
537 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
539 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
540 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
541 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
542 trec->size[recInfo_storeData] = sgml_len;
544 rec_put(records, &trec);
548 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
550 if (!zei->categoryList->dirty)
552 struct zebraCategoryListInfo *zcl = zei->categoryList;
556 zcl->data1_categoryList =
557 data1_read_sgml(zei->dh, zei->nmem,
558 "<explain><categoryList>CategoryList\n"
561 if (zcl->data1_categoryList)
563 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
566 zebraExplain_initCommonInfo(zei, node_cl);
573 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
574 zebAttributeDetails zad)
577 struct zebSUInfoB **zsuip = &zad->SUInfo;
578 data1_node *node_adinfo, *node_zebra, *node_list, *np;
581 rec = rec_get(zei->records, zad->sysno);
583 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
585 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
586 "/attributeDetails");
587 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
589 node_list = data1_search_tag(zei->dh, node_zebra->child,
591 for (np = node_list->child; np; np = np->next)
593 data1_node *node_str = NULL;
594 data1_node *node_ordinal = NULL;
595 data1_node *node_type = NULL;
596 data1_node *node_doc_occurrences = NULL;
597 data1_node *node_term_occurrences = NULL;
600 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
602 for (np2 = np->child; np2; np2 = np2->next)
604 if (np2->which != DATA1N_tag || !np2->child ||
605 np2->child->which != DATA1N_data)
607 if (!strcmp(np2->u.tag.tag, "str"))
608 node_str = np2->child;
609 else if (!strcmp(np2->u.tag.tag, "ordinal"))
610 node_ordinal = np2->child;
611 else if (!strcmp(np2->u.tag.tag, "type"))
612 node_type = np2->child;
613 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
614 node_doc_occurrences = np2->child;
615 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
616 node_term_occurrences = np2->child;
619 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
623 assert(node_ordinal);
625 *zsuip = (struct zebSUInfoB *)
626 nmem_malloc(zei->nmem, sizeof(**zsuip));
628 if (node_type && node_type->u.data.len > 0)
629 (*zsuip)->info.index_type = node_type->u.data.data[0];
632 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
633 (*zsuip)->info.index_type = 'w';
636 if (node_doc_occurrences)
638 data1_node *np = node_doc_occurrences;
639 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
642 if (node_term_occurrences)
644 data1_node *np = node_term_occurrences;
645 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
650 (*zsuip)->info.which = ZEB_SU_STR;
652 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
653 node_str->u.data.data,
654 node_str->u.data.len);
658 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
661 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
662 node_ordinal->u.data.len);
663 zsuip = &(*zsuip)->next;
670 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
671 struct zebDatabaseInfoB *zdi)
674 data1_node *node_dbinfo, *node_zebra, *np;
677 rec = rec_get (zei->records, zdi->sysno);
679 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
681 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
683 assert (node_dbinfo);
684 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
686 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
689 && (np = data1_search_tag (zei->dh, node_zebra->child,
691 && np->child && np->child->which == DATA1N_data)
692 zdi->recordBytes = atoi_zn (np->child->u.data.data,
693 np->child->u.data.len);
696 && (np = data1_search_tag (zei->dh, node_zebra->child,
698 && np->child && np->child->which == DATA1N_data)
699 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
700 np->child->u.data.len);
702 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
704 (np = data1_search_tag (zei->dh, np->child,
705 "recordCountActual")) &&
706 np->child->which == DATA1N_data)
708 zdi->recordCount = atoi_zn (np->child->u.data.data,
709 np->child->u.data.len);
715 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
717 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
721 if (*zdip == zei->curDatabaseInfo)
723 struct zebDatabaseInfoB *zdi = *zdip;
727 zei->updateHandle = update_handle;
729 if (zdi->attributeDetails)
731 /* remove attribute details keys and delete it */
732 zebAttributeDetails zad = zdi->attributeDetails;
734 rec = rec_get(zei->records, zad->sysno);
735 (*zei->updateFunc)(zei->updateHandle, rec, 0);
738 /* remove database record keys and delete it */
739 rec = rec_get (zei->records, zdi->sysno);
740 (*zei->updateFunc)(zei->updateHandle, rec, 0);
743 /* remove from list */
746 /* current database is IR-Explain-1 */
749 zdip = &(*zdip)->next;
754 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
756 struct zebDatabaseInfoB *zdi;
757 const char *database_n = strrchr (database, '/');
762 database_n = database;
765 if (zei->curDatabaseInfo &&
766 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
768 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
770 if (!STRCASECMP (zdi->databaseName, database_n))
776 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
781 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
783 zebraExplain_readDatabase (zei, zdi);
785 if (zdi->attributeDetails->readFlag)
788 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
790 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
792 zei->curDatabaseInfo = zdi;
796 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
798 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
799 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
800 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
801 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
804 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
806 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
808 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
812 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
814 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
815 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
816 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
819 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
820 zebAccessInfo accessInfo)
822 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
828 data1_pr_tree (zei->dh, n, stdout);
833 if ((p = accessInfo->attributeSetIds))
835 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
836 for (; p; p = p->next)
837 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
839 if ((p = accessInfo->schemas))
841 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
842 for (; p; p = p->next)
843 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
847 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
848 int explain_database)
850 struct zebDatabaseInfoB *zdi;
851 data1_node *node_dbinfo, *node_adinfo;
852 const char *database_n = strrchr (database, '/');
857 database_n = database;
860 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
863 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
865 if (!STRCASECMP (zdi->databaseName, database_n))
870 /* it's new really. make it */
871 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
872 zdi->next = zei->databaseInfo;
873 zei->databaseInfo = zdi;
875 zdi->recordCount = 0;
876 zdi->recordBytes = 0;
878 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
880 zdi->ordinalDatabase = zei->ordinalDatabase++;
882 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
887 zdi->data1_database =
888 data1_read_sgml (zei->dh, zei->nmem,
889 "<explain><databaseInfo>DatabaseInfo\n"
891 if (!zdi->data1_database)
894 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
896 assert (node_dbinfo);
898 zebraExplain_initCommonInfo (zei, node_dbinfo);
899 zebraExplain_initAccessInfo (zei, node_dbinfo);
901 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
902 database, zei->nmem);
904 if (explain_database)
905 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
908 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
911 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
915 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
919 zei->curDatabaseInfo = zdi;
921 zdi->attributeDetails = (zebAttributeDetails)
922 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
923 zdi->attributeDetails->readFlag = 0;
924 zdi->attributeDetails->sysno = 0;
925 zdi->attributeDetails->dirty = 1;
926 zdi->attributeDetails->SUInfo = NULL;
927 zdi->attributeDetails->data1_tree =
928 data1_read_sgml (zei->dh, zei->nmem,
929 "<explain><attributeDetails>AttributeDetails\n"
932 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
933 "/attributeDetails");
934 assert (node_adinfo);
936 zebraExplain_initCommonInfo (zei, node_adinfo);
942 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
943 struct zebraCategoryListInfo *zcl,
950 data1_node *node_ci, *node_categoryList;
952 static char *category[] = {
964 node_categoryList = zcl->data1_categoryList;
967 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
970 drec = createRecord (zei->records, &sysno);
974 node_ci = data1_search_tag (zei->dh, node_categoryList,
977 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
981 for (i = 0; category[i]; i++)
983 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
984 0 /* attr */, node_ci);
986 data1_mk_tag_data_text (zei->dh, node_cat, "name",
987 category[i], zei->nmem);
989 /* extract *searchable* keys from it. We do this here, because
990 record count, etc. is affected */
992 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
994 /* convert to "SGML" and write it */
996 data1_pr_tree (zei->dh, node_categoryList, stderr);
998 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
999 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1000 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1001 drec->size[recInfo_storeData] = sgml_len;
1003 rec_put (zei->records, &drec);
1006 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1007 zebAttributeDetails zad,
1008 const char *databaseName,
1014 data1_node *node_adinfo, *node_list, *node_zebra;
1015 struct zebSUInfoB *zsui;
1022 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1025 drec = createRecord (zei->records, &zad->sysno);
1028 assert (zad->data1_tree);
1030 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1031 "/attributeDetails");
1032 zebraExplain_updateCommonInfo (zei, node_adinfo);
1034 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1035 databaseName, zei->nmem);
1037 /* extract *searchable* keys from it. We do this here, because
1038 record count, etc. is affected */
1040 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1041 /* zebra info (private) */
1042 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1043 "zebraInfo", node_adinfo);
1044 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1045 "attrlist", node_zebra);
1046 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1048 data1_node *node_attr;
1049 char index_type_str[2];
1051 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1054 index_type_str[0] = zsui->info.index_type;
1055 index_type_str[1] = '\0';
1056 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1057 index_type_str, zei->nmem);
1058 if (zsui->info.which == ZEB_SU_STR)
1060 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1061 zsui->info.u.str, zei->nmem);
1063 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1064 zsui->info.ordinal, zei->nmem);
1066 data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
1067 zsui->info.doc_occurrences, zei->nmem);
1068 data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
1069 zsui->info.term_occurrences, zei->nmem);
1071 /* convert to "SGML" and write it */
1073 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1075 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1077 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1078 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1079 drec->size[recInfo_storeData] = sgml_len;
1081 rec_put (zei->records, &drec);
1084 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1085 struct zebDatabaseInfoB *zdi,
1091 data1_node *node_dbinfo, *node_count, *node_zebra;
1098 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1100 drec = createRecord (zei->records, &zdi->sysno);
1103 assert (zdi->data1_database);
1105 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1108 assert (node_dbinfo);
1109 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1110 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1112 /* extract *searchable* keys from it. We do this here, because
1113 record count, etc. is affected */
1115 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1117 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1118 "recordCount", node_dbinfo);
1119 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1120 zdi->recordCount, zei->nmem);
1122 /* zebra info (private) */
1123 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1124 "zebraInfo", node_dbinfo);
1125 data1_mk_tag_data_zint (zei->dh, node_zebra,
1126 "recordBytes", zdi->recordBytes, zei->nmem);
1128 data1_mk_tag_data_zint(zei->dh, node_zebra,
1129 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1131 /* convert to "SGML" and write it */
1133 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1135 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1137 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1138 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1139 drec->size[recInfo_storeData] = sgml_len;
1141 rec_put (zei->records, &drec);
1144 static void writeAttributeValues (ZebraExplainInfo zei,
1145 data1_node *node_values,
1146 data1_attset *attset)
1149 data1_attset_child *c;
1154 for (c = attset->children; c; c = c->next)
1155 writeAttributeValues (zei, node_values, c->child);
1156 for (atts = attset->atts; atts; atts = atts->next)
1158 data1_node *node_value;
1160 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1161 0 /* attr */, node_values);
1162 data1_mk_tag_data_text (zei->dh, node_value, "name",
1163 atts->name, zei->nmem);
1164 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1165 0 /* attr */, node_value);
1166 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1167 atts->value, zei->nmem);
1172 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1179 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1180 data1_node *node_values;
1181 struct oident *entp;
1182 struct data1_attset *attset = NULL;
1184 if ((entp = oid_getentbyoid (o->oid)))
1185 attset = data1_attset_search_id (zei->dh, entp->value);
1188 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1189 attset ? attset->name : "<unknown>");
1192 drec = createRecord (zei->records, &o->sysno);
1196 data1_read_sgml (zei->dh, zei->nmem,
1197 "<explain><attributeSetInfo>AttributeSetInfo\n"
1200 node_attinfo = data1_search_tag (zei->dh, node_root,
1201 "/attributeSetInfo");
1203 assert (node_attinfo);
1204 zebraExplain_initCommonInfo (zei, node_attinfo);
1205 zebraExplain_updateCommonInfo (zei, node_attinfo);
1207 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1208 "oid", o->oid, zei->nmem);
1209 if (attset && attset->name)
1210 data1_mk_tag_data_text (zei->dh, node_attinfo,
1211 "name", attset->name, zei->nmem);
1213 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1214 "attributes", node_attinfo);
1215 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1216 "attributeType", node_attributes);
1217 data1_mk_tag_data_text (zei->dh, node_atttype,
1218 "name", "Use", zei->nmem);
1219 data1_mk_tag_data_text (zei->dh, node_atttype,
1220 "description", "Use Attribute", zei->nmem);
1221 data1_mk_tag_data_int (zei->dh, node_atttype,
1222 "type", 1, zei->nmem);
1223 node_values = data1_mk_tag (zei->dh, zei->nmem,
1224 "attributeValues", 0 /* attr */, node_atttype);
1226 writeAttributeValues (zei, node_values, attset);
1228 /* extract *searchable* keys from it. We do this here, because
1229 record count, etc. is affected */
1231 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1232 /* convert to "SGML" and write it */
1234 data1_pr_tree (zei->dh, node_root, stderr);
1236 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1237 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1238 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1239 drec->size[recInfo_storeData] = sgml_len;
1241 rec_put (zei->records, &drec);
1244 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1246 struct zebDatabaseInfoB *zdi;
1247 data1_node *node_tgtinfo, *node_list, *node_zebra;
1256 trec = rec_get_root(zei->records);
1257 xfree (trec->info[recInfo_storeData]);
1259 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1261 assert (node_tgtinfo);
1263 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1264 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1266 /* convert to "SGML" and write it */
1268 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1270 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1271 "zebraInfo", node_tgtinfo);
1272 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1273 ZEBRAVER, zei->nmem);
1274 node_list = data1_mk_tag (zei->dh, zei->nmem,
1275 "databaseList", 0 /* attr */, node_zebra);
1276 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1278 data1_node *node_db;
1279 node_db = data1_mk_tag (zei->dh, zei->nmem,
1280 "database", 0 /* attr */, node_list);
1281 data1_mk_tag_data_text (zei->dh, node_db, "name",
1282 zdi->databaseName, zei->nmem);
1283 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1284 zdi->sysno, zei->nmem);
1285 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1286 zdi->attributeDetails->sysno, zei->nmem);
1288 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1289 zei->ordinalSU, zei->nmem);
1291 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
1292 zei->ordinalDatabase, zei->nmem);
1294 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1295 zei->runNumber, zei->nmem);
1298 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1300 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1302 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1303 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1304 trec->size[recInfo_storeData] = sgml_len;
1306 rec_put (zei->records, &trec);
1309 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
1312 struct zebSUInfoB **zsui;
1314 assert (zei->curDatabaseInfo);
1315 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1316 *zsui; zsui = &(*zsui)->next)
1317 if ((*zsui)->info.index_type == index_type
1318 && (*zsui)->info.which == ZEB_SU_STR
1319 && !yaz_matchstr((*zsui)->info.u.str, str))
1321 struct zebSUInfoB *zsui_this = *zsui;
1323 /* take it out of the list and move to front */
1324 *zsui = (*zsui)->next;
1325 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1326 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1328 return zsui_this->info.ordinal;
1333 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1334 int (*f)(void *handle, int ord))
1336 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1339 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1340 for ( ;zsui; zsui = zsui->next)
1341 (*f)(handle, zsui->info.ordinal);
1347 struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
1351 struct zebDatabaseInfoB *zdb;
1353 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1355 struct zebSUInfoB **zsui;
1357 if (zdb->attributeDetails->readFlag)
1358 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1360 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1361 zsui = &(*zsui)->next)
1362 if ((*zsui)->info.ordinal == ord)
1364 struct zebSUInfoB *zsui_this = *zsui;
1366 /* take it out of the list and move to front */
1367 *zsui = (*zsui)->next;
1368 zsui_this->next = zdb->attributeDetails->SUInfo;
1369 zdb->attributeDetails->SUInfo = zsui_this;
1372 zdb->attributeDetails->dirty = 1;
1374 *db = zdb->databaseName;
1383 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1384 int term_delta, int doc_delta)
1386 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1389 zsui->info.term_occurrences += term_delta;
1390 zsui->info.doc_occurrences += doc_delta;
1396 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1397 zint *term_occurrences,
1398 zint *doc_occurrences)
1400 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1403 *term_occurrences = zsui->info.term_occurrences;
1404 *doc_occurrences = zsui->info.doc_occurrences;
1410 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1412 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1414 return zsui->info.doc_occurrences;
1418 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1420 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1422 return zsui->info.term_occurrences;
1426 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1429 const char **string_index)
1431 struct zebSUInfoB *zsui;
1438 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1441 if (zsui->info.which == ZEB_SU_STR)
1443 *string_index = zsui->info.u.str;
1445 *index_type = zsui->info.index_type;
1453 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1454 zebAccessObject *op,
1459 for (ao = *op; ao; ao = ao->next)
1460 if (!oid_oidcmp (oid, ao->oid))
1464 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1467 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1474 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1479 oe.proto = PROTO_Z3950;
1480 oe.oclass = CLASS_ATTSET;
1481 oe.value = (enum oid_value) set;
1483 if (oid_ent_to_oid (&oe, oid))
1485 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1486 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1487 accessInfo->attributeSetIds, oid);
1491 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1494 struct zebSUInfoB *zsui;
1496 assert (zei->curDatabaseInfo);
1497 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1498 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1499 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1500 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1502 zsui->info.index_type = index_type;
1503 zsui->info.doc_occurrences = 0;
1504 zsui->info.term_occurrences = 0;
1505 zsui->info.ordinal = (zei->ordinalSU)++;
1509 int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
1510 const char *index_name)
1512 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, index_type);
1514 zsui->info.which = ZEB_SU_STR;
1515 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1516 return zsui->info.ordinal;
1519 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1521 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1522 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1523 accessInfo->schemas, oid);
1526 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1528 assert (zei->curDatabaseInfo);
1532 zei->curDatabaseInfo->recordBytes += adjust_num;
1533 zei->curDatabaseInfo->dirty = 1;
1537 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1539 assert (zei->curDatabaseInfo);
1543 zei->curDatabaseInfo->recordCount += adjust_num;
1544 zei->curDatabaseInfo->dirty = 1;
1548 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1554 return zei->runNumber += adjust_num;
1557 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1559 RecordAttr *recordAttr;
1561 if (rec->info[recInfo_attr])
1562 return (RecordAttr *) rec->info[recInfo_attr];
1563 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1564 rec->info[recInfo_attr] = (char *) recordAttr;
1565 rec->size[recInfo_attr] = sizeof(*recordAttr);
1567 recordAttr->recordSize = 0;
1568 recordAttr->recordOffset = 0;
1569 recordAttr->runNumber = zei->runNumber;
1570 recordAttr->staticrank = 0;
1574 static void att_loadset(void *p, const char *n, const char *name)
1576 data1_handle dh = (data1_handle) p;
1577 if (!data1_get_attset (dh, name))
1578 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1581 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1583 if (!zei->curDatabaseInfo)
1585 return zei->curDatabaseInfo->ordinalDatabase;
1588 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1590 res_trav(res, "attset", dh, att_loadset);
1594 zebraExplain_addSU adds to AttributeDetails for a database and
1595 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1596 exist for the database.
1598 If the database doesn't exist globally (in TargetInfo) an
1599 AttributeSetInfo must be added (globally).
1604 * indent-tabs-mode: nil
1606 * vim: shiftwidth=4 tabstop=8 expandtab