1 /* $Id: zinfo.c,v 1.65 2006-05-19 23:20:24 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 int (*updateFunc)(void *handle, Record drec, data1_node *n);
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 int (*updateFunc)(void *handle, Record drec, data1_node *n))
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;
364 zei->categoryList = (struct zebraCategoryListInfo *)
365 nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
366 zei->categoryList->sysno = 0;
367 zei->categoryList->dirty = 0;
368 zei->categoryList->data1_categoryList = NULL;
370 if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
373 tm = localtime(&our_time);
374 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
375 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
376 tm->tm_hour, tm->tm_min, tm->tm_sec);
378 sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
381 zdip = &zei->databaseInfo;
382 trec = rec_get_root(records); /* get "root" record */
387 zebraExplain_mergeAccessInfo(zei, 0, &zei->accessInfo);
388 if (trec) /* targetInfo already exists ... */
390 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
392 zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
394 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
396 if (!zei->data1_target)
399 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
400 nmem_destroy(zei->nmem);
404 data1_pr_tree(zei->dh, zei->data1_target, stderr);
406 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
408 zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
411 node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
416 node_list = data1_search_tag(zei->dh, node_zebra->child,
419 np = node_list->child;
421 for(; np; np = np->next)
423 data1_node *node_name = NULL;
424 data1_node *node_id = NULL;
425 data1_node *node_aid = NULL;
427 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
429 for(np2 = np->child; np2; np2 = np2->next)
431 if (np2->which != DATA1N_tag)
433 if (!strcmp(np2->u.tag.tag, "name"))
434 node_name = np2->child;
435 else if (!strcmp(np2->u.tag.tag, "id"))
436 node_id = np2->child;
437 else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
438 node_aid = np2->child;
440 assert(node_id && node_name && node_aid);
442 *zdip =(struct zebDatabaseInfoB *)
443 nmem_malloc(zei->nmem, sizeof(**zdip));
444 (*zdip)->readFlag = 1;
446 (*zdip)->data1_database = NULL;
447 (*zdip)->recordCount = 0;
448 (*zdip)->recordBytes = 0;
449 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
451 (*zdip)->databaseName = (char *)
452 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
453 memcpy((*zdip)->databaseName, node_name->u.data.data,
454 node_name->u.data.len);
455 (*zdip)->databaseName[node_name->u.data.len] = '\0';
456 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
457 node_id->u.data.len);
458 (*zdip)->attributeDetails = (zebAttributeDetails)
459 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
460 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
461 node_aid->u.data.len);
462 (*zdip)->attributeDetails->readFlag = 1;
463 (*zdip)->attributeDetails->dirty = 0;
464 (*zdip)->attributeDetails->SUInfo = NULL;
466 zdip = &(*zdip)->next;
470 np = data1_search_tag(zei->dh, node_zebra->child,
473 assert (np && np->which == DATA1N_data);
474 zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
476 np = data1_search_tag(zei->dh, node_zebra->child,
479 assert (np && np->which == DATA1N_data);
480 zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
482 np = data1_search_tag(zei->dh, node_zebra->child,
485 assert (np && np->which == DATA1N_data);
486 zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
487 yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
492 else /* create initial targetInfo */
494 data1_node *node_tgtinfo;
503 data1_read_sgml(zei->dh, zei->nmem,
504 "<explain><targetInfo>TargetInfo\n"
506 "<namedResultSets>1</>\n"
507 "<multipleDBSearch>1</>\n"
508 "<nicknames><name>Zebra</></>\n"
510 if (!zei->data1_target)
512 yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
513 nmem_destroy(zei->nmem);
516 node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
518 assert(node_tgtinfo);
520 zebraExplain_initCommonInfo(zei, node_tgtinfo);
521 zebraExplain_initAccessInfo(zei, node_tgtinfo);
523 /* write now because we want to be sure about the sysno */
524 trec = rec_new(records);
527 yaz_log(YLOG_FATAL, "Cannot create root Explain record");
528 nmem_destroy(zei->nmem);
531 trec->info[recInfo_fileType] =
532 rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
533 trec->info[recInfo_databaseName] =
534 rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
536 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
537 trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
538 memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
539 trec->size[recInfo_storeData] = sgml_len;
541 rec_put(records, &trec);
545 zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
547 if (!zei->categoryList->dirty)
549 struct zebraCategoryListInfo *zcl = zei->categoryList;
553 zcl->data1_categoryList =
554 data1_read_sgml(zei->dh, zei->nmem,
555 "<explain><categoryList>CategoryList\n"
558 if (zcl->data1_categoryList)
560 node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
563 zebraExplain_initCommonInfo(zei, node_cl);
570 static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
571 zebAttributeDetails zad)
574 struct zebSUInfoB **zsuip = &zad->SUInfo;
575 data1_node *node_adinfo, *node_zebra, *node_list, *np;
578 rec = rec_get(zei->records, zad->sysno);
580 zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
582 node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
583 "/attributeDetails");
584 node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
586 node_list = data1_search_tag(zei->dh, node_zebra->child,
588 for (np = node_list->child; np; np = np->next)
590 data1_node *node_str = NULL;
591 data1_node *node_ordinal = NULL;
592 data1_node *node_type = NULL;
593 data1_node *node_doc_occurrences = NULL;
594 data1_node *node_term_occurrences = NULL;
597 if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
599 for (np2 = np->child; np2; np2 = np2->next)
601 if (np2->which != DATA1N_tag || !np2->child ||
602 np2->child->which != DATA1N_data)
604 if (!strcmp(np2->u.tag.tag, "str"))
605 node_str = np2->child;
606 else if (!strcmp(np2->u.tag.tag, "ordinal"))
607 node_ordinal = np2->child;
608 else if (!strcmp(np2->u.tag.tag, "type"))
609 node_type = np2->child;
610 else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
611 node_doc_occurrences = np2->child;
612 else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
613 node_term_occurrences = np2->child;
616 yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
620 assert(node_ordinal);
622 *zsuip = (struct zebSUInfoB *)
623 nmem_malloc(zei->nmem, sizeof(**zsuip));
625 if (node_type && node_type->u.data.len > 0)
626 (*zsuip)->info.index_type = node_type->u.data.data[0];
629 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
630 (*zsuip)->info.index_type = 'w';
633 if (node_doc_occurrences)
635 data1_node *np = node_doc_occurrences;
636 (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
639 if (node_term_occurrences)
641 data1_node *np = node_term_occurrences;
642 (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
647 (*zsuip)->info.which = ZEB_SU_STR;
649 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
650 node_str->u.data.data,
651 node_str->u.data.len);
655 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
658 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
659 node_ordinal->u.data.len);
660 zsuip = &(*zsuip)->next;
667 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
668 struct zebDatabaseInfoB *zdi)
671 data1_node *node_dbinfo, *node_zebra, *np;
674 rec = rec_get (zei->records, zdi->sysno);
676 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
678 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
680 assert (node_dbinfo);
681 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
683 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
686 && (np = data1_search_tag (zei->dh, node_zebra->child,
688 && np->child && np->child->which == DATA1N_data)
689 zdi->recordBytes = atoi_zn (np->child->u.data.data,
690 np->child->u.data.len);
693 && (np = data1_search_tag (zei->dh, node_zebra->child,
695 && np->child && np->child->which == DATA1N_data)
696 zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
697 np->child->u.data.len);
699 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
701 (np = data1_search_tag (zei->dh, np->child,
702 "recordCountActual")) &&
703 np->child->which == DATA1N_data)
705 zdi->recordCount = atoi_zn (np->child->u.data.data,
706 np->child->u.data.len);
712 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
714 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
718 if (*zdip == zei->curDatabaseInfo)
720 struct zebDatabaseInfoB *zdi = *zdip;
724 zei->updateHandle = update_handle;
726 if (zdi->attributeDetails)
728 /* remove attribute details keys and delete it */
729 zebAttributeDetails zad = zdi->attributeDetails;
731 rec = rec_get(zei->records, zad->sysno);
732 (*zei->updateFunc)(zei->updateHandle, rec, 0);
735 /* remove database record keys and delete it */
736 rec = rec_get (zei->records, zdi->sysno);
737 (*zei->updateFunc)(zei->updateHandle, rec, 0);
740 /* remove from list */
743 /* current database is IR-Explain-1 */
746 zdip = &(*zdip)->next;
751 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
753 struct zebDatabaseInfoB *zdi;
754 const char *database_n = strrchr (database, '/');
759 database_n = database;
762 if (zei->curDatabaseInfo &&
763 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
765 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
767 if (!STRCASECMP (zdi->databaseName, database_n))
773 yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
778 yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
780 zebraExplain_readDatabase (zei, zdi);
782 if (zdi->attributeDetails->readFlag)
785 yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
787 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
789 zei->curDatabaseInfo = zdi;
793 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
795 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
796 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
797 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
798 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
801 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
803 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
805 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
809 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
811 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
812 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
813 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
816 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
817 zebAccessInfo accessInfo)
819 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
825 data1_pr_tree (zei->dh, n, stdout);
830 if ((p = accessInfo->attributeSetIds))
832 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
833 for (; p; p = p->next)
834 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
836 if ((p = accessInfo->schemas))
838 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
839 for (; p; p = p->next)
840 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
844 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
845 int explain_database)
847 struct zebDatabaseInfoB *zdi;
848 data1_node *node_dbinfo, *node_adinfo;
849 const char *database_n = strrchr (database, '/');
854 database_n = database;
857 yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
860 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
862 if (!STRCASECMP (zdi->databaseName, database_n))
867 /* it's new really. make it */
868 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
869 zdi->next = zei->databaseInfo;
870 zei->databaseInfo = zdi;
872 zdi->recordCount = 0;
873 zdi->recordBytes = 0;
875 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
877 zdi->ordinalDatabase = zei->ordinalDatabase++;
879 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
884 zdi->data1_database =
885 data1_read_sgml (zei->dh, zei->nmem,
886 "<explain><databaseInfo>DatabaseInfo\n"
888 if (!zdi->data1_database)
891 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
893 assert (node_dbinfo);
895 zebraExplain_initCommonInfo (zei, node_dbinfo);
896 zebraExplain_initAccessInfo (zei, node_dbinfo);
898 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
899 database, zei->nmem);
901 if (explain_database)
902 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
905 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
908 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
912 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
916 zei->curDatabaseInfo = zdi;
918 zdi->attributeDetails = (zebAttributeDetails)
919 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
920 zdi->attributeDetails->readFlag = 0;
921 zdi->attributeDetails->sysno = 0;
922 zdi->attributeDetails->dirty = 1;
923 zdi->attributeDetails->SUInfo = NULL;
924 zdi->attributeDetails->data1_tree =
925 data1_read_sgml (zei->dh, zei->nmem,
926 "<explain><attributeDetails>AttributeDetails\n"
929 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
930 "/attributeDetails");
931 assert (node_adinfo);
933 zebraExplain_initCommonInfo (zei, node_adinfo);
939 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
940 struct zebraCategoryListInfo *zcl,
947 data1_node *node_ci, *node_categoryList;
949 static char *category[] = {
961 node_categoryList = zcl->data1_categoryList;
964 yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
967 drec = createRecord (zei->records, &sysno);
971 node_ci = data1_search_tag (zei->dh, node_categoryList,
974 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
978 for (i = 0; category[i]; i++)
980 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
981 0 /* attr */, node_ci);
983 data1_mk_tag_data_text (zei->dh, node_cat, "name",
984 category[i], zei->nmem);
986 /* extract *searchable* keys from it. We do this here, because
987 record count, etc. is affected */
989 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
991 /* convert to "SGML" and write it */
993 data1_pr_tree (zei->dh, node_categoryList, stderr);
995 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
996 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
997 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
998 drec->size[recInfo_storeData] = sgml_len;
1000 rec_put (zei->records, &drec);
1003 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1004 zebAttributeDetails zad,
1005 const char *databaseName,
1011 data1_node *node_adinfo, *node_list, *node_zebra;
1012 struct zebSUInfoB *zsui;
1019 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1022 drec = createRecord (zei->records, &zad->sysno);
1025 assert (zad->data1_tree);
1027 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1028 "/attributeDetails");
1029 zebraExplain_updateCommonInfo (zei, node_adinfo);
1031 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1032 databaseName, zei->nmem);
1034 /* extract *searchable* keys from it. We do this here, because
1035 record count, etc. is affected */
1037 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1038 /* zebra info (private) */
1039 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1040 "zebraInfo", node_adinfo);
1041 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1042 "attrlist", node_zebra);
1043 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1045 data1_node *node_attr;
1046 char index_type_str[2];
1048 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1051 index_type_str[0] = zsui->info.index_type;
1052 index_type_str[1] = '\0';
1053 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1054 index_type_str, zei->nmem);
1055 if (zsui->info.which == ZEB_SU_STR)
1057 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1058 zsui->info.u.str, zei->nmem);
1060 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1061 zsui->info.ordinal, zei->nmem);
1063 data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
1064 zsui->info.doc_occurrences, zei->nmem);
1065 data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
1066 zsui->info.term_occurrences, zei->nmem);
1068 /* convert to "SGML" and write it */
1070 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1072 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1074 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1075 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1076 drec->size[recInfo_storeData] = sgml_len;
1078 rec_put (zei->records, &drec);
1081 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1082 struct zebDatabaseInfoB *zdi,
1088 data1_node *node_dbinfo, *node_count, *node_zebra;
1095 yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1097 drec = createRecord (zei->records, &zdi->sysno);
1100 assert (zdi->data1_database);
1102 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1105 assert (node_dbinfo);
1106 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1107 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1109 /* extract *searchable* keys from it. We do this here, because
1110 record count, etc. is affected */
1112 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1114 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1115 "recordCount", node_dbinfo);
1116 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1117 zdi->recordCount, zei->nmem);
1119 /* zebra info (private) */
1120 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1121 "zebraInfo", node_dbinfo);
1122 data1_mk_tag_data_zint (zei->dh, node_zebra,
1123 "recordBytes", zdi->recordBytes, zei->nmem);
1125 data1_mk_tag_data_zint(zei->dh, node_zebra,
1126 "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1128 /* convert to "SGML" and write it */
1130 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1132 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1134 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1135 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1136 drec->size[recInfo_storeData] = sgml_len;
1138 rec_put (zei->records, &drec);
1141 static void writeAttributeValues (ZebraExplainInfo zei,
1142 data1_node *node_values,
1143 data1_attset *attset)
1146 data1_attset_child *c;
1151 for (c = attset->children; c; c = c->next)
1152 writeAttributeValues (zei, node_values, c->child);
1153 for (atts = attset->atts; atts; atts = atts->next)
1155 data1_node *node_value;
1157 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1158 0 /* attr */, node_values);
1159 data1_mk_tag_data_text (zei->dh, node_value, "name",
1160 atts->name, zei->nmem);
1161 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1162 0 /* attr */, node_value);
1163 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1164 atts->value, zei->nmem);
1169 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1176 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1177 data1_node *node_values;
1178 struct oident *entp;
1179 struct data1_attset *attset = NULL;
1181 if ((entp = oid_getentbyoid (o->oid)))
1182 attset = data1_attset_search_id (zei->dh, entp->value);
1185 yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1186 attset ? attset->name : "<unknown>");
1189 drec = createRecord (zei->records, &o->sysno);
1193 data1_read_sgml (zei->dh, zei->nmem,
1194 "<explain><attributeSetInfo>AttributeSetInfo\n"
1197 node_attinfo = data1_search_tag (zei->dh, node_root,
1198 "/attributeSetInfo");
1200 assert (node_attinfo);
1201 zebraExplain_initCommonInfo (zei, node_attinfo);
1202 zebraExplain_updateCommonInfo (zei, node_attinfo);
1204 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1205 "oid", o->oid, zei->nmem);
1206 if (attset && attset->name)
1207 data1_mk_tag_data_text (zei->dh, node_attinfo,
1208 "name", attset->name, zei->nmem);
1210 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1211 "attributes", node_attinfo);
1212 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1213 "attributeType", node_attributes);
1214 data1_mk_tag_data_text (zei->dh, node_atttype,
1215 "name", "Use", zei->nmem);
1216 data1_mk_tag_data_text (zei->dh, node_atttype,
1217 "description", "Use Attribute", zei->nmem);
1218 data1_mk_tag_data_int (zei->dh, node_atttype,
1219 "type", 1, zei->nmem);
1220 node_values = data1_mk_tag (zei->dh, zei->nmem,
1221 "attributeValues", 0 /* attr */, node_atttype);
1223 writeAttributeValues (zei, node_values, attset);
1225 /* extract *searchable* keys from it. We do this here, because
1226 record count, etc. is affected */
1228 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1229 /* convert to "SGML" and write it */
1231 data1_pr_tree (zei->dh, node_root, stderr);
1233 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1234 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1235 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1236 drec->size[recInfo_storeData] = sgml_len;
1238 rec_put (zei->records, &drec);
1241 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1243 struct zebDatabaseInfoB *zdi;
1244 data1_node *node_tgtinfo, *node_list, *node_zebra;
1253 trec = rec_get_root(zei->records);
1254 xfree (trec->info[recInfo_storeData]);
1256 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1258 assert (node_tgtinfo);
1260 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1261 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1263 /* convert to "SGML" and write it */
1265 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1267 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1268 "zebraInfo", node_tgtinfo);
1269 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1270 ZEBRAVER, zei->nmem);
1271 node_list = data1_mk_tag (zei->dh, zei->nmem,
1272 "databaseList", 0 /* attr */, node_zebra);
1273 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1275 data1_node *node_db;
1276 node_db = data1_mk_tag (zei->dh, zei->nmem,
1277 "database", 0 /* attr */, node_list);
1278 data1_mk_tag_data_text (zei->dh, node_db, "name",
1279 zdi->databaseName, zei->nmem);
1280 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1281 zdi->sysno, zei->nmem);
1282 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1283 zdi->attributeDetails->sysno, zei->nmem);
1285 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1286 zei->ordinalSU, zei->nmem);
1288 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
1289 zei->ordinalDatabase, zei->nmem);
1291 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1292 zei->runNumber, zei->nmem);
1295 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1297 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1299 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1300 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1301 trec->size[recInfo_storeData] = sgml_len;
1303 rec_put (zei->records, &trec);
1306 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
1309 struct zebSUInfoB **zsui;
1311 assert (zei->curDatabaseInfo);
1312 for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1313 *zsui; zsui = &(*zsui)->next)
1314 if ((*zsui)->info.index_type == index_type
1315 && (*zsui)->info.which == ZEB_SU_STR
1316 && !yaz_matchstr((*zsui)->info.u.str, str))
1318 struct zebSUInfoB *zsui_this = *zsui;
1320 /* take it out of the list and move to front */
1321 *zsui = (*zsui)->next;
1322 zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1323 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1325 return zsui_this->info.ordinal;
1330 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1331 int (*f)(void *handle, int ord))
1333 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1336 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1337 for ( ;zsui; zsui = zsui->next)
1338 (*f)(handle, zsui->info.ordinal);
1344 struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
1348 struct zebDatabaseInfoB *zdb;
1350 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1352 struct zebSUInfoB **zsui;
1354 if (zdb->attributeDetails->readFlag)
1355 zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
1357 for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1358 zsui = &(*zsui)->next)
1359 if ((*zsui)->info.ordinal == ord)
1361 struct zebSUInfoB *zsui_this = *zsui;
1363 /* take it out of the list and move to front */
1364 *zsui = (*zsui)->next;
1365 zsui_this->next = zdb->attributeDetails->SUInfo;
1366 zdb->attributeDetails->SUInfo = zsui_this;
1369 zdb->attributeDetails->dirty = 1;
1371 *db = zdb->databaseName;
1380 int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord,
1381 int term_delta, int doc_delta)
1383 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1386 zsui->info.term_occurrences += term_delta;
1387 zsui->info.doc_occurrences += doc_delta;
1393 int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord,
1394 zint *term_occurrences,
1395 zint *doc_occurrences)
1397 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1400 *term_occurrences = zsui->info.term_occurrences;
1401 *doc_occurrences = zsui->info.doc_occurrences;
1407 zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
1409 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1411 return zsui->info.doc_occurrences;
1415 zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
1417 struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1419 return zsui->info.term_occurrences;
1423 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
1426 const char **string_index)
1428 struct zebSUInfoB *zsui;
1435 zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1438 if (zsui->info.which == ZEB_SU_STR)
1440 *string_index = zsui->info.u.str;
1442 *index_type = zsui->info.index_type;
1450 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1451 zebAccessObject *op,
1456 for (ao = *op; ao; ao = ao->next)
1457 if (!oid_oidcmp (oid, ao->oid))
1461 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1464 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1471 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1476 oe.proto = PROTO_Z3950;
1477 oe.oclass = CLASS_ATTSET;
1478 oe.value = (enum oid_value) set;
1480 if (oid_ent_to_oid (&oe, oid))
1482 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1483 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1484 accessInfo->attributeSetIds, oid);
1488 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
1491 struct zebSUInfoB *zsui;
1493 assert (zei->curDatabaseInfo);
1494 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1495 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1496 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1497 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1499 zsui->info.index_type = index_type;
1500 zsui->info.doc_occurrences = 0;
1501 zsui->info.term_occurrences = 0;
1502 zsui->info.ordinal = (zei->ordinalSU)++;
1506 int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
1507 const char *index_name)
1509 struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, index_type);
1511 zsui->info.which = ZEB_SU_STR;
1512 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1513 return zsui->info.ordinal;
1516 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1518 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1519 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1520 accessInfo->schemas, oid);
1523 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1525 assert (zei->curDatabaseInfo);
1529 zei->curDatabaseInfo->recordBytes += adjust_num;
1530 zei->curDatabaseInfo->dirty = 1;
1534 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1536 assert (zei->curDatabaseInfo);
1540 zei->curDatabaseInfo->recordCount += adjust_num;
1541 zei->curDatabaseInfo->dirty = 1;
1545 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1551 return zei->runNumber += adjust_num;
1554 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1556 RecordAttr *recordAttr;
1558 if (rec->info[recInfo_attr])
1559 return (RecordAttr *) rec->info[recInfo_attr];
1560 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1561 rec->info[recInfo_attr] = (char *) recordAttr;
1562 rec->size[recInfo_attr] = sizeof(*recordAttr);
1564 recordAttr->recordSize = 0;
1565 recordAttr->recordOffset = 0;
1566 recordAttr->runNumber = zei->runNumber;
1567 recordAttr->staticrank = 0;
1571 static void att_loadset(void *p, const char *n, const char *name)
1573 data1_handle dh = (data1_handle) p;
1574 if (!data1_get_attset (dh, name))
1575 yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1578 int zebraExplain_get_database_ord(ZebraExplainInfo zei)
1580 if (!zei->curDatabaseInfo)
1582 return zei->curDatabaseInfo->ordinalDatabase;
1585 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1587 res_trav(res, "attset", dh, att_loadset);
1591 zebraExplain_addSU adds to AttributeDetails for a database and
1592 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1593 exist for the database.
1595 If the database doesn't exist globally (in TargetInfo) an
1596 AttributeSetInfo must be added (globally).
1601 * indent-tabs-mode: nil
1603 * vim: shiftwidth=4 tabstop=8 expandtab