1 /* $Id: zinfo.c,v 1.52 2005-12-08 11:10:03 adam Exp $
2 Copyright (C) 1995-2005
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
50 struct zebSUInfo info;
51 struct zebSUInfoB *next;
54 typedef struct zebAccessObjectB *zebAccessObject;
55 struct zebAccessObjectB {
62 typedef struct zebAccessInfoB *zebAccessInfo;
63 struct zebAccessInfoB {
64 zebAccessObject attributeSetIds;
65 zebAccessObject schemas;
69 struct zebSUInfoB *SUInfo;
73 data1_node *data1_tree;
74 } *zebAttributeDetails;
76 struct zebDatabaseInfoB {
77 zebAttributeDetails attributeDetails;
79 data1_node *data1_database;
80 zint recordCount; /* records in db */
81 zint recordBytes; /* size of records */
82 SYSNO sysno; /* sysno of database info */
83 int readFlag; /* 1: read is needed when referenced; 0 if not */
84 int dirty; /* 1: database is dirty: write is needed */
85 struct zebDatabaseInfoB *next;
86 zebAccessInfo accessInfo;
89 struct zebraExplainAttset {
92 struct zebraExplainAttset *next;
95 struct zebraCategoryListInfo {
98 data1_node *data1_categoryList;
101 struct zebraExplainInfo {
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);
151 xfree (rec->info[recInfo_storeData]);
155 rec = rec_new (records);
158 rec->info[recInfo_fileType] =
159 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
160 rec->info[recInfo_databaseName] =
161 rec_strdup ("IR-Explain-1",
162 &rec->size[recInfo_databaseName]);
167 void zebraExplain_flush (ZebraExplainInfo zei, void *handle)
171 zei->updateHandle = handle;
174 struct zebDatabaseInfoB *zdi;
177 /* write each database info record */
178 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
180 zebraExplain_writeDatabase (zei, zdi, 1);
181 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
182 zdi->databaseName, 1);
184 zebraExplain_writeTarget (zei, 1);
185 zebraExplain_writeCategoryList (zei,
188 assert (zei->accessInfo);
189 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
191 zebraExplain_writeAttributeSet (zei, o, 1);
192 for (o = zei->accessInfo->schemas; o; o = o->next)
195 /* zebraExplain_writeSchema (zei, o, 1); */
198 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
200 zebraExplain_writeDatabase (zei, zdi, 0);
201 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
202 zdi->databaseName, 0);
204 zebraExplain_writeTarget (zei, 0);
208 void zebraExplain_close (ZebraExplainInfo zei)
211 yaz_log (YLOG_LOG, "zebraExplain_close");
215 zebraExplain_flush (zei, zei->updateHandle);
216 nmem_destroy (zei->nmem);
219 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
224 for (np = n->child; np; np = np->next)
231 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
233 len = np->child->u.data.len;
236 memcpy (str, np->child->u.data.data, len);
239 oid = odr_getoidbystr_nmem (zei->nmem, str);
241 for (ao = *op; ao; ao = ao->next)
242 if (!oid_oidcmp (oid, ao->oid))
249 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
259 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
260 zebAccessInfo *accessInfo)
266 *accessInfo = (zebAccessInfo)
267 nmem_malloc (zei->nmem, sizeof(**accessInfo));
268 (*accessInfo)->attributeSetIds = NULL;
269 (*accessInfo)->schemas = NULL;
273 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
275 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
276 zebraExplain_mergeOids (zei, np,
277 &(*accessInfo)->attributeSetIds);
278 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
279 zebraExplain_mergeOids (zei, np,
280 &(*accessInfo)->schemas);
289 databaseList (list of databases)
294 targetInfo: TargetInfo
301 dateAdded: 20030630190601
302 dateChanged: 20030630190601
308 oid: 1.2.840.10003.3.2
309 oid: 1.2.840.10003.3.5
310 oid: 1.2.840.10003.3.1
312 oid: 1.2.840.10003.13.1000.81.2
313 oid: 1.2.840.10003.13.2
320 attributeDetailsId: 51
324 attributeDetailsId: 53
327 nextResultSetPosition = 2
330 ZebraExplainInfo zebraExplain_open (
331 Records records, data1_handle dh,
335 int (*updateFunc)(void *handle, Record drec, data1_node *n))
338 ZebraExplainInfo zei;
339 struct zebDatabaseInfoB **zdip;
342 NMEM nmem = nmem_create ();
345 yaz_log (YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
347 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
348 zei->databaseInfo = 0;
349 zei->write_flag = writeFlag;
350 zei->updateHandle = updateHandle;
351 zei->updateFunc = updateFunc;
353 zei->curDatabaseInfo = NULL;
354 zei->records = records;
359 zei->categoryList = (struct zebraCategoryListInfo *)
360 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
361 zei->categoryList->sysno = 0;
362 zei->categoryList->dirty = 0;
363 zei->categoryList->data1_categoryList = NULL;
365 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
368 tm = localtime (&our_time);
369 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
370 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
371 tm->tm_hour, tm->tm_min, tm->tm_sec);
373 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
376 zdip = &zei->databaseInfo;
377 trec = rec_get_root(records); /* get "root" record */
382 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
383 if (trec) /* targetInfo already exists ... */
385 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
387 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
389 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
391 if (!zei->data1_target)
394 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
395 nmem_destroy (zei->nmem);
399 data1_pr_tree (zei->dh, zei->data1_target, stderr);
401 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
403 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
406 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
411 node_list = data1_search_tag (zei->dh, node_zebra->child,
414 np = node_list->child;
416 for (; np; np = np->next)
418 data1_node *node_name = NULL;
419 data1_node *node_id = NULL;
420 data1_node *node_aid = NULL;
422 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
424 for (np2 = np->child; np2; np2 = np2->next)
426 if (np2->which != DATA1N_tag)
428 if (!strcmp (np2->u.tag.tag, "name"))
429 node_name = np2->child;
430 else if (!strcmp (np2->u.tag.tag, "id"))
431 node_id = np2->child;
432 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
433 node_aid = np2->child;
435 assert (node_id && node_name && node_aid);
437 *zdip = (struct zebDatabaseInfoB *)
438 nmem_malloc (zei->nmem, sizeof(**zdip));
439 (*zdip)->readFlag = 1;
441 (*zdip)->data1_database = NULL;
442 (*zdip)->recordCount = 0;
443 (*zdip)->recordBytes = 0;
444 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
446 (*zdip)->databaseName = (char *)
447 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
448 memcpy ((*zdip)->databaseName, node_name->u.data.data,
449 node_name->u.data.len);
450 (*zdip)->databaseName[node_name->u.data.len] = '\0';
451 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
452 node_id->u.data.len);
453 (*zdip)->attributeDetails = (zebAttributeDetails)
454 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
455 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
456 node_aid->u.data.len);
457 (*zdip)->attributeDetails->readFlag = 1;
458 (*zdip)->attributeDetails->dirty = 0;
459 (*zdip)->attributeDetails->SUInfo = NULL;
461 zdip = &(*zdip)->next;
465 np = data1_search_tag (zei->dh, node_zebra->child,
468 assert (np && np->which == DATA1N_data);
469 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
471 np = data1_search_tag (zei->dh, node_zebra->child,
474 assert (np && np->which == DATA1N_data);
475 zei->runNumber = atoi_zn (np->u.data.data, np->u.data.len);
476 yaz_log (YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
481 else /* create initial targetInfo */
483 data1_node *node_tgtinfo;
492 data1_read_sgml (zei->dh, zei->nmem,
493 "<explain><targetInfo>TargetInfo\n"
495 "<namedResultSets>1</>\n"
496 "<multipleDBSearch>1</>\n"
497 "<nicknames><name>Zebra</></>\n"
499 if (!zei->data1_target)
501 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
502 nmem_destroy (zei->nmem);
505 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
507 assert (node_tgtinfo);
509 zebraExplain_initCommonInfo (zei, node_tgtinfo);
510 zebraExplain_initAccessInfo (zei, node_tgtinfo);
512 /* write now because we want to be sure about the sysno */
513 trec = rec_new (records);
514 trec->info[recInfo_fileType] =
515 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
516 trec->info[recInfo_databaseName] =
517 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
519 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
520 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
521 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
522 trec->size[recInfo_storeData] = sgml_len;
524 rec_put (records, &trec);
528 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
530 if (!zei->categoryList->dirty)
532 struct zebraCategoryListInfo *zcl = zei->categoryList;
536 zcl->data1_categoryList =
537 data1_read_sgml (zei->dh, zei->nmem,
538 "<explain><categoryList>CategoryList\n"
541 if (zcl->data1_categoryList)
543 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
546 zebraExplain_initCommonInfo (zei, node_cl);
553 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
554 zebAttributeDetails zad)
557 struct zebSUInfoB **zsuip = &zad->SUInfo;
558 data1_node *node_adinfo, *node_zebra, *node_list, *np;
561 rec = rec_get (zei->records, zad->sysno);
563 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
565 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
566 "/attributeDetails");
567 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
569 node_list = data1_search_tag (zei->dh, node_zebra->child,
571 for (np = node_list->child; np; np = np->next)
573 data1_node *node_set = NULL;
574 data1_node *node_use = NULL;
575 data1_node *node_str = NULL;
576 data1_node *node_ordinal = NULL;
577 data1_node *node_type = NULL;
582 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
584 for (np2 = np->child; np2; np2 = np2->next)
586 if (np2->which != DATA1N_tag || !np2->child ||
587 np2->child->which != DATA1N_data)
589 if (!strcmp (np2->u.tag.tag, "set"))
590 node_set = np2->child;
591 else if (!strcmp (np2->u.tag.tag, "use"))
592 node_use = np2->child;
593 else if (!strcmp (np2->u.tag.tag, "str"))
594 node_str = np2->child;
595 else if (!strcmp (np2->u.tag.tag, "ordinal"))
596 node_ordinal = np2->child;
597 else if (!strcmp (np2->u.tag.tag, "type"))
598 node_type = np2->child;
600 assert (node_ordinal);
602 *zsuip = (struct zebSUInfoB *)
603 nmem_malloc (zei->nmem, sizeof(**zsuip));
605 if (node_type && node_type->u.data.len > 0)
606 (*zsuip)->info.index_type = node_type->u.data.data[0];
609 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
610 (*zsuip)->info.index_type = 'w';
613 if (node_set && node_use)
615 (*zsuip)->info.which = ZEB_SU_SET_USE;
617 oid_str_len = node_set->u.data.len;
618 if (oid_str_len >= (int) sizeof(oid_str))
619 oid_str_len = sizeof(oid_str)-1;
620 memcpy (oid_str, node_set->u.data.data, oid_str_len);
621 oid_str[oid_str_len] = '\0';
623 (*zsuip)->info.u.su.set = oid_getvalbyname (oid_str);
625 (*zsuip)->info.u.su.use = atoi_n (node_use->u.data.data,
626 node_use->u.data.len);
627 yaz_log (YLOG_DEBUG, "set=%d use=%d ordinal=%d",
628 (*zsuip)->info.u.su.set, (*zsuip)->info.u.su.use,
629 (*zsuip)->info.ordinal);
633 (*zsuip)->info.which = ZEB_SU_STR;
635 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
636 node_str->u.data.data,
637 node_str->u.data.len);
641 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
644 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
645 node_ordinal->u.data.len);
646 zsuip = &(*zsuip)->next;
653 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
654 struct zebDatabaseInfoB *zdi)
657 data1_node *node_dbinfo, *node_zebra, *np;
660 rec = rec_get (zei->records, zdi->sysno);
662 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
664 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
666 assert (node_dbinfo);
667 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
669 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
672 && (np = data1_search_tag (zei->dh, node_zebra->child,
674 && np->child && np->child->which == DATA1N_data)
675 zdi->recordBytes = atoi_zn (np->child->u.data.data,
676 np->child->u.data.len);
677 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
679 (np = data1_search_tag (zei->dh, np->child,
680 "recordCountActual")) &&
681 np->child->which == DATA1N_data)
683 zdi->recordCount = atoi_zn (np->child->u.data.data,
684 np->child->u.data.len);
690 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
692 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
696 if (*zdip == zei->curDatabaseInfo)
698 struct zebDatabaseInfoB *zdi = *zdip;
702 zei->updateHandle = update_handle;
704 if (zdi->attributeDetails)
706 /* remove attribute details keys and delete it */
707 zebAttributeDetails zad = zdi->attributeDetails;
709 rec = rec_get(zei->records, zad->sysno);
710 (*zei->updateFunc)(zei->updateHandle, rec, 0);
713 /* remove database record keys and delete it */
714 rec = rec_get (zei->records, zdi->sysno);
715 (*zei->updateFunc)(zei->updateHandle, rec, 0);
718 /* remove from list */
721 /* current database is IR-Explain-1 */
724 zdip = &(*zdip)->next;
729 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
731 struct zebDatabaseInfoB *zdi;
732 const char *database_n = strrchr (database, '/');
737 database_n = database;
740 if (zei->curDatabaseInfo &&
741 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
743 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
745 if (!STRCASECMP (zdi->databaseName, database_n))
751 yaz_log (YLOG_LOG, "zebraExplain_curDatabase: %s", database);
756 yaz_log (YLOG_LOG, "zebraExplain_readDatabase: %s", database);
758 zebraExplain_readDatabase (zei, zdi);
760 if (zdi->attributeDetails->readFlag)
763 yaz_log (YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
765 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
767 zei->curDatabaseInfo = zdi;
771 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
773 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
774 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
775 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
776 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
779 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
781 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
783 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
787 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
789 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
790 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
791 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
794 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
795 zebAccessInfo accessInfo)
797 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
803 data1_pr_tree (zei->dh, n, stdout);
808 if ((p = accessInfo->attributeSetIds))
810 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
811 for (; p; p = p->next)
812 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
814 if ((p = accessInfo->schemas))
816 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
817 for (; p; p = p->next)
818 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
822 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
823 int explain_database)
825 struct zebDatabaseInfoB *zdi;
826 data1_node *node_dbinfo, *node_adinfo;
827 const char *database_n = strrchr (database, '/');
832 database_n = database;
835 yaz_log (YLOG_LOG, "zebraExplain_newDatabase: %s", database);
838 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
840 if (!STRCASECMP (zdi->databaseName, database_n))
845 /* it's new really. make it */
846 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
847 zdi->next = zei->databaseInfo;
848 zei->databaseInfo = zdi;
850 zdi->recordCount = 0;
851 zdi->recordBytes = 0;
853 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
855 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
860 zdi->data1_database =
861 data1_read_sgml (zei->dh, zei->nmem,
862 "<explain><databaseInfo>DatabaseInfo\n"
864 if (!zdi->data1_database)
867 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
869 assert (node_dbinfo);
871 zebraExplain_initCommonInfo (zei, node_dbinfo);
872 zebraExplain_initAccessInfo (zei, node_dbinfo);
874 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
875 database, zei->nmem);
877 if (explain_database)
878 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
881 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
884 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
888 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
892 zei->curDatabaseInfo = zdi;
894 zdi->attributeDetails = (zebAttributeDetails)
895 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
896 zdi->attributeDetails->readFlag = 0;
897 zdi->attributeDetails->sysno = 0;
898 zdi->attributeDetails->dirty = 1;
899 zdi->attributeDetails->SUInfo = NULL;
900 zdi->attributeDetails->data1_tree =
901 data1_read_sgml (zei->dh, zei->nmem,
902 "<explain><attributeDetails>AttributeDetails\n"
905 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
906 "/attributeDetails");
907 assert (node_adinfo);
909 zebraExplain_initCommonInfo (zei, node_adinfo);
914 static void writeAttributeValueDetails (ZebraExplainInfo zei,
915 zebAttributeDetails zad,
916 data1_node *node_atvs, data1_attset *attset)
919 struct zebSUInfoB *zsui;
920 int set_ordinal = attset->reference;
921 data1_attset_child *c;
923 for (c = attset->children; c; c = c->next)
924 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
925 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
927 if (zsui->info.which == ZEB_SU_SET_USE &&
928 set_ordinal == zsui->info.u.su.set)
930 data1_node *node_attvalue, *node_value;
931 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
932 0 /* attr */, node_atvs);
933 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
934 0 /* attr */, node_attvalue);
935 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
936 zsui->info.u.su.use, zei->nmem);
941 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
942 struct zebraCategoryListInfo *zcl,
949 data1_node *node_ci, *node_categoryList;
951 static char *category[] = {
963 node_categoryList = zcl->data1_categoryList;
966 yaz_log (YLOG_LOG, "zebraExplain_writeCategoryList");
969 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, *node_attributesBySet;
1012 struct zebSUInfoB *zsui;
1020 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeDetails");
1023 drec = createRecord (zei->records, &zad->sysno);
1024 assert (zad->data1_tree);
1026 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1027 "/attributeDetails");
1028 zebraExplain_updateCommonInfo (zei, node_adinfo);
1030 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1031 databaseName, zei->nmem);
1033 /* extract *searchable* keys from it. We do this here, because
1034 record count, etc. is affected */
1036 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1038 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
1039 "attributesBySet", node_adinfo);
1043 data1_node *node_asd;
1044 data1_attset *attset;
1045 int set_ordinal = -1;
1046 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1048 if (zsui->info.which == ZEB_SU_SET_USE &&
1049 (set_ordinal < 0 || set_ordinal > zsui->info.u.su.set)
1050 && zsui->info.u.su.set > set_min)
1051 set_ordinal = zsui->info.u.su.set;
1053 if (set_ordinal < 0)
1055 set_min = set_ordinal;
1056 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1057 "attributeSetDetails",
1058 0 /* attr */, node_attributesBySet);
1060 attset = data1_attset_search_id (zei->dh, set_ordinal);
1063 zebraExplain_loadAttsets (zei->dh, zei->res);
1064 attset = data1_attset_search_id (zei->dh, set_ordinal);
1071 oe.proto = PROTO_Z3950;
1072 oe.oclass = CLASS_ATTSET;
1073 oe.value = (enum oid_value) set_ordinal;
1075 if (oid_ent_to_oid (&oe, oid))
1077 data1_node *node_abt, *node_atd, *node_atvs;
1078 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1081 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1083 0 /*attr */, node_asd);
1084 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1085 "attributeTypeDetails",
1086 0 /* attr */, node_abt);
1087 data1_mk_tag_data_int (zei->dh, node_atd,
1088 "type", 1, zei->nmem);
1089 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1091 0 /* attr */, node_atd);
1092 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1096 /* zebra info (private) */
1097 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1098 "zebraInfo", node_adinfo);
1099 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1100 "attrlist", node_zebra);
1101 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1103 struct oident oident;
1105 data1_node *node_attr;
1106 char index_type_str[2];
1109 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1112 index_type_str[0] = zsui->info.index_type;
1113 index_type_str[1] = '\0';
1114 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1115 index_type_str, zei->nmem);
1116 if (zsui->info.which == ZEB_SU_SET_USE)
1118 oident.proto = PROTO_Z3950;
1119 oident.oclass = CLASS_ATTSET;
1120 oident.value = (enum oid_value) zsui->info.u.su.set;
1121 oid_ent_to_oid (&oident, oid);
1123 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1124 oident.desc, zei->nmem);
1125 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1126 zsui->info.u.su.use, zei->nmem);
1128 else if (zsui->info.which == ZEB_SU_STR)
1130 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1131 zsui->info.u.str, zei->nmem);
1133 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1134 zsui->info.ordinal, zei->nmem);
1136 /* convert to "SGML" and write it */
1138 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1140 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1142 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1143 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1144 drec->size[recInfo_storeData] = sgml_len;
1146 rec_put (zei->records, &drec);
1149 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1150 struct zebDatabaseInfoB *zdi,
1156 data1_node *node_dbinfo, *node_count, *node_zebra;
1163 yaz_log (YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1165 drec = createRecord (zei->records, &zdi->sysno);
1166 assert (zdi->data1_database);
1168 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1171 assert (node_dbinfo);
1172 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1173 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1175 /* extract *searchable* keys from it. We do this here, because
1176 record count, etc. is affected */
1178 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1180 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1181 "recordCount", node_dbinfo);
1182 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1183 zdi->recordCount, zei->nmem);
1185 /* zebra info (private) */
1186 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1187 "zebraInfo", node_dbinfo);
1188 data1_mk_tag_data_zint (zei->dh, node_zebra,
1189 "recordBytes", zdi->recordBytes, zei->nmem);
1190 /* convert to "SGML" and write it */
1192 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1194 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1196 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1197 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1198 drec->size[recInfo_storeData] = sgml_len;
1200 rec_put (zei->records, &drec);
1203 static void writeAttributeValues (ZebraExplainInfo zei,
1204 data1_node *node_values,
1205 data1_attset *attset)
1208 data1_attset_child *c;
1213 for (c = attset->children; c; c = c->next)
1214 writeAttributeValues (zei, node_values, c->child);
1215 for (atts = attset->atts; atts; atts = atts->next)
1217 data1_node *node_value;
1219 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1220 0 /* attr */, node_values);
1221 data1_mk_tag_data_text (zei->dh, node_value, "name",
1222 atts->name, zei->nmem);
1223 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1224 0 /* attr */, node_value);
1225 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1226 atts->value, zei->nmem);
1231 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1238 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1239 data1_node *node_values;
1240 struct oident *entp;
1241 struct data1_attset *attset = NULL;
1243 if ((entp = oid_getentbyoid (o->oid)))
1244 attset = data1_attset_search_id (zei->dh, entp->value);
1247 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1248 attset ? attset->name : "<unknown>");
1251 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 /* convert to "SGML" and write it */
1325 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1327 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1328 "zebraInfo", node_tgtinfo);
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_zint (zei->dh, node_zebra, "runNumber",
1349 zei->runNumber, zei->nmem);
1352 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1354 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1356 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1357 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1358 trec->size[recInfo_storeData] = sgml_len;
1360 rec_put (zei->records, &trec);
1363 int zebraExplain_lookup_attr_su_any_index(ZebraExplainInfo zei,
1366 struct zebSUInfoB *zsui;
1368 assert (zei->curDatabaseInfo);
1369 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1370 zsui; zsui=zsui->next)
1371 if (zsui->info.which == ZEB_SU_SET_USE &&
1372 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1373 return zsui->info.ordinal;
1377 int zebraExplain_lookup_attr_su(ZebraExplainInfo zei, int index_type,
1380 struct zebSUInfoB *zsui;
1382 assert (zei->curDatabaseInfo);
1383 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1384 zsui; zsui=zsui->next)
1385 if (zsui->info.index_type == index_type &&
1386 zsui->info.which == ZEB_SU_SET_USE &&
1387 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1388 return zsui->info.ordinal;
1392 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
1395 struct zebSUInfoB *zsui;
1397 assert (zei->curDatabaseInfo);
1398 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1399 zsui; zsui=zsui->next)
1400 if (zsui->info.index_type == index_type &&
1401 zsui->info.which == ZEB_SU_STR && !strcmp(zsui->info.u.str, str))
1402 return zsui->info.ordinal;
1406 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1407 int (*f)(void *handle, int ord))
1409 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1412 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1413 for ( ;zsui; zsui = zsui->next)
1414 (*f)(handle, zsui->info.ordinal);
1419 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1424 struct zebDatabaseInfoB *zdb;
1425 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1427 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1428 for ( ;zsui; zsui = zsui->next)
1429 if (zsui->info.ordinal == ord)
1432 *db = zdb->databaseName;
1433 if (zsui->info.which == ZEB_SU_SET_USE)
1436 *set = zsui->info.u.su.set;
1438 *use = zsui->info.u.su.use;
1441 *index_type = zsui->info.index_type;
1448 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1449 zebAccessObject *op,
1454 for (ao = *op; ao; ao = ao->next)
1455 if (!oid_oidcmp (oid, ao->oid))
1459 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1462 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1469 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1474 oe.proto = PROTO_Z3950;
1475 oe.oclass = CLASS_ATTSET;
1476 oe.value = (enum oid_value) set;
1478 if (oid_ent_to_oid (&oe, oid))
1480 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1481 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1482 accessInfo->attributeSetIds, oid);
1486 int zebraExplain_add_attr_su(ZebraExplainInfo zei, int index_type,
1489 struct zebSUInfoB *zsui;
1491 assert (zei->curDatabaseInfo);
1492 zebraExplain_addAttributeSet (zei, set);
1493 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1494 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1495 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1496 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1498 zsui->info.index_type = index_type;
1499 zsui->info.which = ZEB_SU_SET_USE;
1500 zsui->info.u.su.set = set;
1501 zsui->info.u.su.use = use;
1502 zsui->info.ordinal = (zei->ordinalSU)++;
1503 return zsui->info.ordinal;
1506 int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
1507 const char *index_name)
1509 struct zebSUInfoB *zsui;
1511 assert (zei->curDatabaseInfo);
1512 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1513 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1514 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1515 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1517 zsui->info.index_type = index_type;
1518 zsui->info.which = ZEB_SU_STR;
1519 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1520 zsui->info.ordinal = (zei->ordinalSU)++;
1521 return zsui->info.ordinal;
1524 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1526 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1527 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1528 accessInfo->schemas, oid);
1531 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1533 assert (zei->curDatabaseInfo);
1537 zei->curDatabaseInfo->recordBytes += adjust_num;
1538 zei->curDatabaseInfo->dirty = 1;
1542 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1544 assert (zei->curDatabaseInfo);
1548 zei->curDatabaseInfo->recordCount += adjust_num;
1549 zei->curDatabaseInfo->dirty = 1;
1553 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1559 return zei->runNumber += adjust_num;
1562 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1564 RecordAttr *recordAttr;
1566 if (rec->info[recInfo_attr])
1567 return (RecordAttr *) rec->info[recInfo_attr];
1568 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1569 rec->info[recInfo_attr] = (char *) recordAttr;
1570 rec->size[recInfo_attr] = sizeof(*recordAttr);
1572 recordAttr->recordSize = 0;
1573 recordAttr->recordOffset = 0;
1574 recordAttr->runNumber = zei->runNumber;
1575 recordAttr->staticrank = 0;
1579 static void att_loadset(void *p, const char *n, const char *name)
1581 data1_handle dh = (data1_handle) p;
1582 if (!data1_get_attset (dh, name))
1583 yaz_log (YLOG_WARN, "Directive attset failed for %s", name);
1586 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1588 res_trav(res, "attset", dh, att_loadset);
1592 zebraExplain_addSU adds to AttributeDetails for a database and
1593 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1594 exist for the database.
1596 If the database doesn't exist globally (in TargetInfo) an
1597 AttributeSetInfo must be added (globally).