1 /* $Id: zinfo.c,v 1.48 2005-08-09 12:30:46 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->write_flag = writeFlag;
349 zei->updateHandle = updateHandle;
350 zei->updateFunc = updateFunc;
352 zei->curDatabaseInfo = NULL;
353 zei->records = records;
358 zei->categoryList = (struct zebraCategoryListInfo *)
359 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
360 zei->categoryList->sysno = 0;
361 zei->categoryList->dirty = 0;
362 zei->categoryList->data1_categoryList = NULL;
364 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
367 tm = localtime (&our_time);
368 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
369 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
370 tm->tm_hour, tm->tm_min, tm->tm_sec);
372 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
375 zdip = &zei->databaseInfo;
376 trec = rec_get_root(records); /* get "root" record */
381 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
382 if (trec) /* targetInfo already exists ... */
384 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
386 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
388 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
390 if (!zei->data1_target)
393 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
394 nmem_destroy (zei->nmem);
398 data1_pr_tree (zei->dh, zei->data1_target, stderr);
400 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
402 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
405 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
410 node_list = data1_search_tag (zei->dh, node_zebra->child,
413 np = node_list->child;
415 for (; np; np = np->next)
417 data1_node *node_name = NULL;
418 data1_node *node_id = NULL;
419 data1_node *node_aid = NULL;
421 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
423 for (np2 = np->child; np2; np2 = np2->next)
425 if (np2->which != DATA1N_tag)
427 if (!strcmp (np2->u.tag.tag, "name"))
428 node_name = np2->child;
429 else if (!strcmp (np2->u.tag.tag, "id"))
430 node_id = np2->child;
431 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
432 node_aid = np2->child;
434 assert (node_id && node_name && node_aid);
436 *zdip = (struct zebDatabaseInfoB *)
437 nmem_malloc (zei->nmem, sizeof(**zdip));
438 (*zdip)->readFlag = 1;
440 (*zdip)->data1_database = NULL;
441 (*zdip)->recordCount = 0;
442 (*zdip)->recordBytes = 0;
443 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
445 (*zdip)->databaseName = (char *)
446 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
447 memcpy ((*zdip)->databaseName, node_name->u.data.data,
448 node_name->u.data.len);
449 (*zdip)->databaseName[node_name->u.data.len] = '\0';
450 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
451 node_id->u.data.len);
452 (*zdip)->attributeDetails = (zebAttributeDetails)
453 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
454 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
455 node_aid->u.data.len);
456 (*zdip)->attributeDetails->readFlag = 1;
457 (*zdip)->attributeDetails->dirty = 0;
458 (*zdip)->attributeDetails->SUInfo = NULL;
460 zdip = &(*zdip)->next;
464 np = data1_search_tag (zei->dh, node_zebra->child,
467 assert (np && np->which == DATA1N_data);
468 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
470 np = data1_search_tag (zei->dh, node_zebra->child,
473 assert (np && np->which == DATA1N_data);
474 zei->runNumber = atoi_zn (np->u.data.data, np->u.data.len);
475 yaz_log (YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
480 else /* create initial targetInfo */
482 data1_node *node_tgtinfo;
491 data1_read_sgml (zei->dh, zei->nmem,
492 "<explain><targetInfo>TargetInfo\n"
494 "<namedResultSets>1</>\n"
495 "<multipleDBSearch>1</>\n"
496 "<nicknames><name>Zebra</></>\n"
498 if (!zei->data1_target)
500 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
501 nmem_destroy (zei->nmem);
504 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
506 assert (node_tgtinfo);
508 zebraExplain_initCommonInfo (zei, node_tgtinfo);
509 zebraExplain_initAccessInfo (zei, node_tgtinfo);
511 /* write now because we want to be sure about the sysno */
512 trec = rec_new (records);
513 trec->info[recInfo_fileType] =
514 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
515 trec->info[recInfo_databaseName] =
516 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
518 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
519 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
520 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
521 trec->size[recInfo_storeData] = sgml_len;
523 rec_put (records, &trec);
527 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
529 if (!zei->categoryList->dirty)
531 struct zebraCategoryListInfo *zcl = zei->categoryList;
535 zcl->data1_categoryList =
536 data1_read_sgml (zei->dh, zei->nmem,
537 "<explain><categoryList>CategoryList\n"
540 if (zcl->data1_categoryList)
542 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
545 zebraExplain_initCommonInfo (zei, node_cl);
552 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
553 zebAttributeDetails zad)
556 struct zebSUInfoB **zsuip = &zad->SUInfo;
557 data1_node *node_adinfo, *node_zebra, *node_list, *np;
560 rec = rec_get (zei->records, zad->sysno);
562 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
564 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
565 "/attributeDetails");
566 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
568 node_list = data1_search_tag (zei->dh, node_zebra->child,
570 for (np = node_list->child; np; np = np->next)
572 data1_node *node_set = NULL;
573 data1_node *node_use = NULL;
574 data1_node *node_str = NULL;
575 data1_node *node_ordinal = NULL;
576 data1_node *node_type = NULL;
581 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
583 for (np2 = np->child; np2; np2 = np2->next)
585 if (np2->which != DATA1N_tag || !np2->child ||
586 np2->child->which != DATA1N_data)
588 if (!strcmp (np2->u.tag.tag, "set"))
589 node_set = np2->child;
590 else if (!strcmp (np2->u.tag.tag, "use"))
591 node_use = np2->child;
592 else if (!strcmp (np2->u.tag.tag, "str"))
593 node_str = np2->child;
594 else if (!strcmp (np2->u.tag.tag, "ordinal"))
595 node_ordinal = np2->child;
596 else if (!strcmp (np2->u.tag.tag, "type"))
597 node_type = np2->child;
599 assert (node_ordinal);
601 *zsuip = (struct zebSUInfoB *)
602 nmem_malloc (zei->nmem, sizeof(**zsuip));
604 if (node_type && node_type->u.data.len > 0)
605 (*zsuip)->info.index_type = node_type->u.data.data[0];
608 yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
609 (*zsuip)->info.index_type = 'w';
612 if (node_set && node_use)
614 (*zsuip)->info.which = ZEB_SU_SET_USE;
616 oid_str_len = node_set->u.data.len;
617 if (oid_str_len >= (int) sizeof(oid_str))
618 oid_str_len = sizeof(oid_str)-1;
619 memcpy (oid_str, node_set->u.data.data, oid_str_len);
620 oid_str[oid_str_len] = '\0';
622 (*zsuip)->info.u.su.set = oid_getvalbyname (oid_str);
624 (*zsuip)->info.u.su.use = atoi_n (node_use->u.data.data,
625 node_use->u.data.len);
626 yaz_log (YLOG_DEBUG, "set=%d use=%d ordinal=%d",
627 (*zsuip)->info.u.su.set, (*zsuip)->info.u.su.use,
628 (*zsuip)->info.ordinal);
632 (*zsuip)->info.which = ZEB_SU_STR;
634 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
635 node_str->u.data.data,
636 node_str->u.data.len);
640 yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
643 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
644 node_ordinal->u.data.len);
645 zsuip = &(*zsuip)->next;
652 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
653 struct zebDatabaseInfoB *zdi)
656 data1_node *node_dbinfo, *node_zebra, *np;
659 rec = rec_get (zei->records, zdi->sysno);
661 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
663 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
665 assert (node_dbinfo);
666 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
668 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
671 && (np = data1_search_tag (zei->dh, node_zebra->child,
673 && np->child && np->child->which == DATA1N_data)
674 zdi->recordBytes = atoi_zn (np->child->u.data.data,
675 np->child->u.data.len);
676 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
678 (np = data1_search_tag (zei->dh, np->child,
679 "recordCountActual")) &&
680 np->child->which == DATA1N_data)
682 zdi->recordCount = atoi_zn (np->child->u.data.data,
683 np->child->u.data.len);
689 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
691 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
695 if (*zdip == zei->curDatabaseInfo)
697 struct zebDatabaseInfoB *zdi = *zdip;
701 zei->updateHandle = update_handle;
703 if (zdi->attributeDetails)
705 /* remove attribute details keys and delete it */
706 zebAttributeDetails zad = zdi->attributeDetails;
708 rec = rec_get(zei->records, zad->sysno);
709 (*zei->updateFunc)(zei->updateHandle, rec, 0);
712 /* remove database record keys and delete it */
713 rec = rec_get (zei->records, zdi->sysno);
714 (*zei->updateFunc)(zei->updateHandle, rec, 0);
717 /* remove from list */
720 /* current database is IR-Explain-1 */
723 zdip = &(*zdip)->next;
728 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
730 struct zebDatabaseInfoB *zdi;
731 const char *database_n = strrchr (database, '/');
736 database_n = database;
739 if (zei->curDatabaseInfo &&
740 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
742 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
744 if (!STRCASECMP (zdi->databaseName, database_n))
750 yaz_log (YLOG_LOG, "zebraExplain_curDatabase: %s", database);
755 yaz_log (YLOG_LOG, "zebraExplain_readDatabase: %s", database);
757 zebraExplain_readDatabase (zei, zdi);
759 if (zdi->attributeDetails->readFlag)
762 yaz_log (YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
764 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
766 zei->curDatabaseInfo = zdi;
770 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
772 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
773 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
774 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
775 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
778 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
780 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
782 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
786 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
788 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
789 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
790 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
793 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
794 zebAccessInfo accessInfo)
796 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
802 data1_pr_tree (zei->dh, n, stdout);
807 if ((p = accessInfo->attributeSetIds))
809 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
810 for (; p; p = p->next)
811 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
813 if ((p = accessInfo->schemas))
815 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
816 for (; p; p = p->next)
817 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
821 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
822 int explain_database)
824 struct zebDatabaseInfoB *zdi;
825 data1_node *node_dbinfo, *node_adinfo;
826 const char *database_n = strrchr (database, '/');
831 database_n = database;
834 yaz_log (YLOG_LOG, "zebraExplain_newDatabase: %s", database);
837 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
839 if (!STRCASECMP (zdi->databaseName, database_n))
844 /* it's new really. make it */
845 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
846 zdi->next = zei->databaseInfo;
847 zei->databaseInfo = zdi;
849 zdi->recordCount = 0;
850 zdi->recordBytes = 0;
852 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
854 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
859 zdi->data1_database =
860 data1_read_sgml (zei->dh, zei->nmem,
861 "<explain><databaseInfo>DatabaseInfo\n"
863 if (!zdi->data1_database)
866 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
868 assert (node_dbinfo);
870 zebraExplain_initCommonInfo (zei, node_dbinfo);
871 zebraExplain_initAccessInfo (zei, node_dbinfo);
873 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
874 database, zei->nmem);
876 if (explain_database)
877 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
880 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
883 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
887 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
891 zei->curDatabaseInfo = zdi;
893 zdi->attributeDetails = (zebAttributeDetails)
894 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
895 zdi->attributeDetails->readFlag = 0;
896 zdi->attributeDetails->sysno = 0;
897 zdi->attributeDetails->dirty = 1;
898 zdi->attributeDetails->SUInfo = NULL;
899 zdi->attributeDetails->data1_tree =
900 data1_read_sgml (zei->dh, zei->nmem,
901 "<explain><attributeDetails>AttributeDetails\n"
904 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
905 "/attributeDetails");
906 assert (node_adinfo);
908 zebraExplain_initCommonInfo (zei, node_adinfo);
913 static void writeAttributeValueDetails (ZebraExplainInfo zei,
914 zebAttributeDetails zad,
915 data1_node *node_atvs, data1_attset *attset)
918 struct zebSUInfoB *zsui;
919 int set_ordinal = attset->reference;
920 data1_attset_child *c;
922 for (c = attset->children; c; c = c->next)
923 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
924 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
926 if (zsui->info.which == ZEB_SU_SET_USE &&
927 set_ordinal == zsui->info.u.su.set)
929 data1_node *node_attvalue, *node_value;
930 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
931 0 /* attr */, node_atvs);
932 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
933 0 /* attr */, node_attvalue);
934 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
935 zsui->info.u.su.use, zei->nmem);
940 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
941 struct zebraCategoryListInfo *zcl,
948 data1_node *node_ci, *node_categoryList;
950 static char *category[] = {
962 node_categoryList = zcl->data1_categoryList;
965 yaz_log (YLOG_LOG, "zebraExplain_writeCategoryList");
968 drec = createRecord (zei->records, &sysno);
970 node_ci = data1_search_tag (zei->dh, node_categoryList,
973 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
977 for (i = 0; category[i]; i++)
979 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
980 0 /* attr */, node_ci);
982 data1_mk_tag_data_text (zei->dh, node_cat, "name",
983 category[i], zei->nmem);
985 /* extract *searchable* keys from it. We do this here, because
986 record count, etc. is affected */
988 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
990 /* convert to "SGML" and write it */
992 data1_pr_tree (zei->dh, node_categoryList, stderr);
994 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
995 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
996 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
997 drec->size[recInfo_storeData] = sgml_len;
999 rec_put (zei->records, &drec);
1002 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
1003 zebAttributeDetails zad,
1004 const char *databaseName,
1010 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
1011 struct zebSUInfoB *zsui;
1019 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeDetails");
1022 drec = createRecord (zei->records, &zad->sysno);
1023 assert (zad->data1_tree);
1025 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1026 "/attributeDetails");
1027 zebraExplain_updateCommonInfo (zei, node_adinfo);
1029 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1030 databaseName, zei->nmem);
1032 /* extract *searchable* keys from it. We do this here, because
1033 record count, etc. is affected */
1035 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1037 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
1038 "attributesBySet", node_adinfo);
1042 data1_node *node_asd;
1043 data1_attset *attset;
1044 int set_ordinal = -1;
1045 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1047 if (zsui->info.which == ZEB_SU_SET_USE &&
1048 (set_ordinal < 0 || set_ordinal > zsui->info.u.su.set)
1049 && zsui->info.u.su.set > set_min)
1050 set_ordinal = zsui->info.u.su.set;
1052 if (set_ordinal < 0)
1054 set_min = set_ordinal;
1055 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1056 "attributeSetDetails",
1057 0 /* attr */, node_attributesBySet);
1059 attset = data1_attset_search_id (zei->dh, set_ordinal);
1062 zebraExplain_loadAttsets (zei->dh, zei->res);
1063 attset = data1_attset_search_id (zei->dh, set_ordinal);
1070 oe.proto = PROTO_Z3950;
1071 oe.oclass = CLASS_ATTSET;
1072 oe.value = (enum oid_value) set_ordinal;
1074 if (oid_ent_to_oid (&oe, oid))
1076 data1_node *node_abt, *node_atd, *node_atvs;
1077 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1080 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1082 0 /*attr */, node_asd);
1083 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1084 "attributeTypeDetails",
1085 0 /* attr */, node_abt);
1086 data1_mk_tag_data_int (zei->dh, node_atd,
1087 "type", 1, zei->nmem);
1088 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1090 0 /* attr */, node_atd);
1091 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1095 /* zebra info (private) */
1096 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1097 "zebraInfo", node_adinfo);
1098 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1099 "attrlist", node_zebra);
1100 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1102 struct oident oident;
1104 data1_node *node_attr;
1105 char index_type_str[2];
1108 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1111 index_type_str[0] = zsui->info.index_type;
1112 index_type_str[1] = '\0';
1113 data1_mk_tag_data_text (zei->dh, node_attr, "type",
1114 index_type_str, zei->nmem);
1115 if (zsui->info.which == ZEB_SU_SET_USE)
1117 oident.proto = PROTO_Z3950;
1118 oident.oclass = CLASS_ATTSET;
1119 oident.value = (enum oid_value) zsui->info.u.su.set;
1120 oid_ent_to_oid (&oident, oid);
1122 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1123 oident.desc, zei->nmem);
1124 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1125 zsui->info.u.su.use, zei->nmem);
1127 else if (zsui->info.which == ZEB_SU_STR)
1129 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1130 zsui->info.u.str, zei->nmem);
1132 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1133 zsui->info.ordinal, zei->nmem);
1135 /* convert to "SGML" and write it */
1137 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1139 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1141 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1142 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1143 drec->size[recInfo_storeData] = sgml_len;
1145 rec_put (zei->records, &drec);
1148 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1149 struct zebDatabaseInfoB *zdi,
1155 data1_node *node_dbinfo, *node_count, *node_zebra;
1162 yaz_log (YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1164 drec = createRecord (zei->records, &zdi->sysno);
1165 assert (zdi->data1_database);
1167 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1170 assert (node_dbinfo);
1171 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1172 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1174 /* extract *searchable* keys from it. We do this here, because
1175 record count, etc. is affected */
1177 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1179 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1180 "recordCount", node_dbinfo);
1181 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1182 zdi->recordCount, zei->nmem);
1184 /* zebra info (private) */
1185 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1186 "zebraInfo", node_dbinfo);
1187 data1_mk_tag_data_zint (zei->dh, node_zebra,
1188 "recordBytes", zdi->recordBytes, zei->nmem);
1189 /* convert to "SGML" and write it */
1191 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1193 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1195 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1196 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1197 drec->size[recInfo_storeData] = sgml_len;
1199 rec_put (zei->records, &drec);
1202 static void writeAttributeValues (ZebraExplainInfo zei,
1203 data1_node *node_values,
1204 data1_attset *attset)
1207 data1_attset_child *c;
1212 for (c = attset->children; c; c = c->next)
1213 writeAttributeValues (zei, node_values, c->child);
1214 for (atts = attset->atts; atts; atts = atts->next)
1216 data1_node *node_value;
1218 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1219 0 /* attr */, node_values);
1220 data1_mk_tag_data_text (zei->dh, node_value, "name",
1221 atts->name, zei->nmem);
1222 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1223 0 /* attr */, node_value);
1224 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1225 atts->value, zei->nmem);
1230 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1237 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1238 data1_node *node_values;
1239 struct oident *entp;
1240 struct data1_attset *attset = NULL;
1242 if ((entp = oid_getentbyoid (o->oid)))
1243 attset = data1_attset_search_id (zei->dh, entp->value);
1246 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1247 attset ? attset->name : "<unknown>");
1250 drec = createRecord (zei->records, &o->sysno);
1252 data1_read_sgml (zei->dh, zei->nmem,
1253 "<explain><attributeSetInfo>AttributeSetInfo\n"
1256 node_attinfo = data1_search_tag (zei->dh, node_root,
1257 "/attributeSetInfo");
1259 assert (node_attinfo);
1260 zebraExplain_initCommonInfo (zei, node_attinfo);
1261 zebraExplain_updateCommonInfo (zei, node_attinfo);
1263 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1264 "oid", o->oid, zei->nmem);
1265 if (attset && attset->name)
1266 data1_mk_tag_data_text (zei->dh, node_attinfo,
1267 "name", attset->name, zei->nmem);
1269 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1270 "attributes", node_attinfo);
1271 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1272 "attributeType", node_attributes);
1273 data1_mk_tag_data_text (zei->dh, node_atttype,
1274 "name", "Use", zei->nmem);
1275 data1_mk_tag_data_text (zei->dh, node_atttype,
1276 "description", "Use Attribute", zei->nmem);
1277 data1_mk_tag_data_int (zei->dh, node_atttype,
1278 "type", 1, zei->nmem);
1279 node_values = data1_mk_tag (zei->dh, zei->nmem,
1280 "attributeValues", 0 /* attr */, node_atttype);
1282 writeAttributeValues (zei, node_values, attset);
1284 /* extract *searchable* keys from it. We do this here, because
1285 record count, etc. is affected */
1287 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1288 /* convert to "SGML" and write it */
1290 data1_pr_tree (zei->dh, node_root, stderr);
1292 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1293 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1294 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1295 drec->size[recInfo_storeData] = sgml_len;
1297 rec_put (zei->records, &drec);
1300 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1302 struct zebDatabaseInfoB *zdi;
1303 data1_node *node_tgtinfo, *node_list, *node_zebra;
1312 trec = rec_get_root(zei->records);
1313 xfree (trec->info[recInfo_storeData]);
1315 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1317 assert (node_tgtinfo);
1319 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1320 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1322 /* convert to "SGML" and write it */
1324 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1326 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1327 "zebraInfo", node_tgtinfo);
1328 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1329 ZEBRAVER, zei->nmem);
1330 node_list = data1_mk_tag (zei->dh, zei->nmem,
1331 "databaseList", 0 /* attr */, node_zebra);
1332 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1334 data1_node *node_db;
1335 node_db = data1_mk_tag (zei->dh, zei->nmem,
1336 "database", 0 /* attr */, node_list);
1337 data1_mk_tag_data_text (zei->dh, node_db, "name",
1338 zdi->databaseName, zei->nmem);
1339 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1340 zdi->sysno, zei->nmem);
1341 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1342 zdi->attributeDetails->sysno, zei->nmem);
1344 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1345 zei->ordinalSU, zei->nmem);
1347 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1348 zei->runNumber, zei->nmem);
1351 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1353 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1355 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1356 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1357 trec->size[recInfo_storeData] = sgml_len;
1359 rec_put (zei->records, &trec);
1362 int zebraExplain_lookup_attr_su_any_index(ZebraExplainInfo zei,
1365 struct zebSUInfoB *zsui;
1367 assert (zei->curDatabaseInfo);
1368 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1369 zsui; zsui=zsui->next)
1370 if (zsui->info.which == ZEB_SU_SET_USE &&
1371 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1372 return zsui->info.ordinal;
1376 int zebraExplain_lookup_attr_su(ZebraExplainInfo zei, int index_type,
1379 struct zebSUInfoB *zsui;
1381 assert (zei->curDatabaseInfo);
1382 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1383 zsui; zsui=zsui->next)
1384 if (zsui->info.index_type == index_type &&
1385 zsui->info.which == ZEB_SU_SET_USE &&
1386 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1387 return zsui->info.ordinal;
1391 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
1394 struct zebSUInfoB *zsui;
1396 assert (zei->curDatabaseInfo);
1397 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1398 zsui; zsui=zsui->next)
1399 if (zsui->info.index_type == index_type &&
1400 zsui->info.which == ZEB_SU_STR && !strcmp(zsui->info.u.str, str))
1401 return zsui->info.ordinal;
1405 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1406 int (*f)(void *handle, int ord))
1408 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1411 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1412 for ( ;zsui; zsui = zsui->next)
1413 (*f)(handle, zsui->info.ordinal);
1418 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1419 const char **db, int *set, int *use)
1421 struct zebDatabaseInfoB *zdb;
1422 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1424 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1425 for ( ;zsui; zsui = zsui->next)
1426 if (zsui->info.which == ZEB_SU_SET_USE &&
1427 zsui->info.ordinal == ord)
1429 *db = zdb->databaseName;
1430 *set = zsui->info.u.su.set;
1431 *use = zsui->info.u.su.use;
1438 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1439 zebAccessObject *op,
1444 for (ao = *op; ao; ao = ao->next)
1445 if (!oid_oidcmp (oid, ao->oid))
1449 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1452 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1459 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1464 oe.proto = PROTO_Z3950;
1465 oe.oclass = CLASS_ATTSET;
1466 oe.value = (enum oid_value) set;
1468 if (oid_ent_to_oid (&oe, oid))
1470 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1471 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1472 accessInfo->attributeSetIds, oid);
1476 int zebraExplain_add_attr_su(ZebraExplainInfo zei, int index_type,
1479 struct zebSUInfoB *zsui;
1481 assert (zei->curDatabaseInfo);
1482 zebraExplain_addAttributeSet (zei, set);
1483 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1484 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1485 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1486 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1488 zsui->info.index_type = index_type;
1489 zsui->info.which = ZEB_SU_SET_USE;
1490 zsui->info.u.su.set = set;
1491 zsui->info.u.su.use = use;
1492 zsui->info.ordinal = (zei->ordinalSU)++;
1493 return zsui->info.ordinal;
1496 int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
1497 const char *index_name)
1499 struct zebSUInfoB *zsui;
1501 assert (zei->curDatabaseInfo);
1502 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1503 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1504 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1505 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1507 zsui->info.index_type = index_type;
1508 zsui->info.which = ZEB_SU_STR;
1509 zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
1510 zsui->info.ordinal = (zei->ordinalSU)++;
1511 return zsui->info.ordinal;
1514 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1516 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1517 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1518 accessInfo->schemas, oid);
1521 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1523 assert (zei->curDatabaseInfo);
1527 zei->curDatabaseInfo->recordBytes += adjust_num;
1528 zei->curDatabaseInfo->dirty = 1;
1532 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1534 assert (zei->curDatabaseInfo);
1538 zei->curDatabaseInfo->recordCount += adjust_num;
1539 zei->curDatabaseInfo->dirty = 1;
1543 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1549 return zei->runNumber += adjust_num;
1552 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1554 RecordAttr *recordAttr;
1556 if (rec->info[recInfo_attr])
1557 return (RecordAttr *) rec->info[recInfo_attr];
1558 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1559 rec->info[recInfo_attr] = (char *) recordAttr;
1560 rec->size[recInfo_attr] = sizeof(*recordAttr);
1562 recordAttr->recordSize = 0;
1563 recordAttr->recordOffset = 0;
1564 recordAttr->runNumber = zei->runNumber;
1568 static void att_loadset(void *p, const char *n, const char *name)
1570 data1_handle dh = (data1_handle) p;
1571 if (!data1_get_attset (dh, name))
1572 yaz_log (YLOG_WARN, "Directive attset failed for %s", name);
1575 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1577 res_trav(res, "attset", dh, att_loadset);
1581 zebraExplain_addSU adds to AttributeDetails for a database and
1582 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1583 exist for the database.
1585 If the database doesn't exist globally (in TargetInfo) an
1586 AttributeSetInfo must be added (globally).