1 /* $Id: zinfo.c,v 1.45 2005-03-05 09:19:14 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>
35 #define ZEB_SU_SET_USE 1
49 struct zebSUInfo info;
50 struct zebSUInfoB *next;
53 typedef struct zebAccessObjectB *zebAccessObject;
54 struct zebAccessObjectB {
61 typedef struct zebAccessInfoB *zebAccessInfo;
62 struct zebAccessInfoB {
63 zebAccessObject attributeSetIds;
64 zebAccessObject schemas;
68 struct zebSUInfoB *SUInfo;
72 data1_node *data1_tree;
73 } *zebAttributeDetails;
75 struct zebDatabaseInfoB {
76 zebAttributeDetails attributeDetails;
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 {
108 struct zebraExplainAttset *attsets;
110 data1_node *data1_target;
111 struct zebraCategoryListInfo *categoryList;
112 struct zebDatabaseInfoB *databaseInfo;
113 struct zebDatabaseInfoB *curDatabaseInfo;
114 zebAccessInfo accessInfo;
115 char date[15]; /* YYYY MMDD HH MM SS */
116 int (*updateFunc)(void *handle, Record drec, data1_node *n);
120 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
121 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
123 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
125 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
128 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
129 struct zebDatabaseInfoB *zdi,
131 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
132 zebAttributeDetails zad,
133 const char *databaseName,
135 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
136 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
139 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
140 struct zebraCategoryListInfo *zcl,
144 static Record createRecord (Records records, SYSNO *sysno)
149 rec = rec_get (records, *sysno);
150 xfree (rec->info[recInfo_storeData]);
154 rec = rec_new (records);
157 rec->info[recInfo_fileType] =
158 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
159 rec->info[recInfo_databaseName] =
160 rec_strdup ("IR-Explain-1",
161 &rec->size[recInfo_databaseName]);
166 void zebraExplain_flush (ZebraExplainInfo zei, void *handle)
170 zei->updateHandle = handle;
173 struct zebDatabaseInfoB *zdi;
176 /* write each database info record */
177 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
179 zebraExplain_writeDatabase (zei, zdi, 1);
180 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
181 zdi->databaseName, 1);
183 zebraExplain_writeTarget (zei, 1);
184 zebraExplain_writeCategoryList (zei,
187 assert (zei->accessInfo);
188 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
190 zebraExplain_writeAttributeSet (zei, o, 1);
191 for (o = zei->accessInfo->schemas; o; o = o->next)
194 /* zebraExplain_writeSchema (zei, o, 1); */
197 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
199 zebraExplain_writeDatabase (zei, zdi, 0);
200 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
201 zdi->databaseName, 0);
203 zebraExplain_writeTarget (zei, 0);
207 void zebraExplain_close (ZebraExplainInfo zei)
210 yaz_log (YLOG_LOG, "zebraExplain_close");
214 zebraExplain_flush (zei, zei->updateHandle);
215 nmem_destroy (zei->nmem);
218 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
223 for (np = n->child; np; np = np->next)
230 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
232 len = np->child->u.data.len;
235 memcpy (str, np->child->u.data.data, len);
238 oid = odr_getoidbystr_nmem (zei->nmem, str);
240 for (ao = *op; ao; ao = ao->next)
241 if (!oid_oidcmp (oid, ao->oid))
248 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
258 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
259 zebAccessInfo *accessInfo)
265 *accessInfo = (zebAccessInfo)
266 nmem_malloc (zei->nmem, sizeof(**accessInfo));
267 (*accessInfo)->attributeSetIds = NULL;
268 (*accessInfo)->schemas = NULL;
272 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
274 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
275 zebraExplain_mergeOids (zei, np,
276 &(*accessInfo)->attributeSetIds);
277 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
278 zebraExplain_mergeOids (zei, np,
279 &(*accessInfo)->schemas);
288 databaseList (list of databases)
293 targetInfo: TargetInfo
300 dateAdded: 20030630190601
301 dateChanged: 20030630190601
307 oid: 1.2.840.10003.3.2
308 oid: 1.2.840.10003.3.5
309 oid: 1.2.840.10003.3.1
311 oid: 1.2.840.10003.13.1000.81.2
312 oid: 1.2.840.10003.13.2
319 attributeDetailsId: 51
323 attributeDetailsId: 53
326 nextResultSetPosition = 2
329 ZebraExplainInfo zebraExplain_open (
330 Records records, data1_handle dh,
334 int (*updateFunc)(void *handle, Record drec, data1_node *n))
337 ZebraExplainInfo zei;
338 struct zebDatabaseInfoB **zdip;
341 NMEM nmem = nmem_create ();
344 yaz_log (YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
346 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
347 zei->write_flag = writeFlag;
348 zei->updateHandle = updateHandle;
349 zei->updateFunc = updateFunc;
351 zei->curDatabaseInfo = NULL;
352 zei->records = records;
357 zei->categoryList = (struct zebraCategoryListInfo *)
358 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
359 zei->categoryList->sysno = 0;
360 zei->categoryList->dirty = 0;
361 zei->categoryList->data1_categoryList = NULL;
363 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
366 tm = localtime (&our_time);
367 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
368 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
369 tm->tm_hour, tm->tm_min, tm->tm_sec);
371 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
374 zdip = &zei->databaseInfo;
375 trec = rec_get (records, 1); /* get "root" record */
380 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
381 if (trec) /* targetInfo already exists ... */
383 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
385 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
387 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
389 if (!zei->data1_target)
392 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
393 nmem_destroy (zei->nmem);
397 data1_pr_tree (zei->dh, zei->data1_target, stderr);
399 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
401 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
404 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
409 node_list = data1_search_tag (zei->dh, node_zebra->child,
412 np = node_list->child;
414 for (; np; np = np->next)
416 data1_node *node_name = NULL;
417 data1_node *node_id = NULL;
418 data1_node *node_aid = NULL;
420 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
422 for (np2 = np->child; np2; np2 = np2->next)
424 if (np2->which != DATA1N_tag)
426 if (!strcmp (np2->u.tag.tag, "name"))
427 node_name = np2->child;
428 else if (!strcmp (np2->u.tag.tag, "id"))
429 node_id = np2->child;
430 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
431 node_aid = np2->child;
433 assert (node_id && node_name && node_aid);
435 *zdip = (struct zebDatabaseInfoB *)
436 nmem_malloc (zei->nmem, sizeof(**zdip));
437 (*zdip)->readFlag = 1;
439 (*zdip)->data1_database = NULL;
440 (*zdip)->recordCount = 0;
441 (*zdip)->recordBytes = 0;
442 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
444 (*zdip)->databaseName = (char *)
445 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
446 memcpy ((*zdip)->databaseName, node_name->u.data.data,
447 node_name->u.data.len);
448 (*zdip)->databaseName[node_name->u.data.len] = '\0';
449 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
450 node_id->u.data.len);
451 (*zdip)->attributeDetails = (zebAttributeDetails)
452 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
453 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
454 node_aid->u.data.len);
455 (*zdip)->attributeDetails->readFlag = 1;
456 (*zdip)->attributeDetails->dirty = 0;
457 (*zdip)->attributeDetails->SUInfo = NULL;
459 zdip = &(*zdip)->next;
463 np = data1_search_tag (zei->dh, node_zebra->child,
466 assert (np && np->which == DATA1N_data);
467 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
469 np = data1_search_tag (zei->dh, node_zebra->child,
472 assert (np && np->which == DATA1N_data);
473 zei->runNumber = atoi_zn (np->u.data.data, np->u.data.len);
474 yaz_log (YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
479 else /* create initial targetInfo */
481 data1_node *node_tgtinfo;
490 data1_read_sgml (zei->dh, zei->nmem,
491 "<explain><targetInfo>TargetInfo\n"
493 "<namedResultSets>1</>\n"
494 "<multipleDBSearch>1</>\n"
495 "<nicknames><name>Zebra</></>\n"
497 if (!zei->data1_target)
499 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
500 nmem_destroy (zei->nmem);
503 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
505 assert (node_tgtinfo);
507 zebraExplain_initCommonInfo (zei, node_tgtinfo);
508 zebraExplain_initAccessInfo (zei, node_tgtinfo);
510 /* write now because we want to be sure about the sysno */
511 trec = rec_new (records);
512 trec->info[recInfo_fileType] =
513 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
514 trec->info[recInfo_databaseName] =
515 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
517 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
518 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
519 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
520 trec->size[recInfo_storeData] = sgml_len;
522 rec_put (records, &trec);
526 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
528 if (!zei->categoryList->dirty)
530 struct zebraCategoryListInfo *zcl = zei->categoryList;
534 zcl->data1_categoryList =
535 data1_read_sgml (zei->dh, zei->nmem,
536 "<explain><categoryList>CategoryList\n"
539 if (zcl->data1_categoryList)
541 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
544 zebraExplain_initCommonInfo (zei, node_cl);
551 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
552 zebAttributeDetails zad)
555 struct zebSUInfoB **zsuip = &zad->SUInfo;
556 data1_node *node_adinfo, *node_zebra, *node_list, *np;
559 rec = rec_get (zei->records, zad->sysno);
561 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
563 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
564 "/attributeDetails");
565 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
567 node_list = data1_search_tag (zei->dh, node_zebra->child,
569 for (np = node_list->child; np; np = np->next)
571 data1_node *node_set = NULL;
572 data1_node *node_use = NULL;
573 data1_node *node_str = NULL;
574 data1_node *node_ordinal = NULL;
579 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
581 for (np2 = np->child; np2; np2 = np2->next)
583 if (np2->which != DATA1N_tag || !np2->child ||
584 np2->child->which != DATA1N_data)
586 if (!strcmp (np2->u.tag.tag, "set"))
587 node_set = np2->child;
588 else if (!strcmp (np2->u.tag.tag, "use"))
589 node_use = np2->child;
590 else if (!strcmp (np2->u.tag.tag, "str"))
591 node_str = np2->child;
592 else if (!strcmp (np2->u.tag.tag, "ordinal"))
593 node_ordinal = np2->child;
595 assert (node_ordinal);
597 *zsuip = (struct zebSUInfoB *)
598 nmem_malloc (zei->nmem, sizeof(**zsuip));
599 if (node_set && node_use)
601 (*zsuip)->info.which = ZEB_SU_SET_USE;
603 oid_str_len = node_set->u.data.len;
604 if (oid_str_len >= (int) sizeof(oid_str))
605 oid_str_len = sizeof(oid_str)-1;
606 memcpy (oid_str, node_set->u.data.data, oid_str_len);
607 oid_str[oid_str_len] = '\0';
609 (*zsuip)->info.u.su.set = oid_getvalbyname (oid_str);
611 (*zsuip)->info.u.su.use = atoi_n (node_use->u.data.data,
612 node_use->u.data.len);
613 yaz_log (YLOG_DEBUG, "set=%d use=%d ordinal=%d",
614 (*zsuip)->info.u.su.set, (*zsuip)->info.u.su.use,
615 (*zsuip)->info.ordinal);
619 (*zsuip)->info.which = ZEB_SU_STR;
621 (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
622 node_str->u.data.data,
623 node_str->u.data.len);
627 yaz_log(YLOG_WARN, "Missng set/use/str in attribute info");
630 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
631 node_ordinal->u.data.len);
632 zsuip = &(*zsuip)->next;
639 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
640 struct zebDatabaseInfoB *zdi)
643 data1_node *node_dbinfo, *node_zebra, *np;
646 rec = rec_get (zei->records, zdi->sysno);
648 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
650 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
652 assert (node_dbinfo);
653 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
655 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
658 && (np = data1_search_tag (zei->dh, node_zebra->child,
660 && np->child && np->child->which == DATA1N_data)
661 zdi->recordBytes = atoi_zn (np->child->u.data.data,
662 np->child->u.data.len);
663 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
665 (np = data1_search_tag (zei->dh, np->child,
666 "recordCountActual")) &&
667 np->child->which == DATA1N_data)
669 zdi->recordCount = atoi_zn (np->child->u.data.data,
670 np->child->u.data.len);
676 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
678 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
682 if (*zdip == zei->curDatabaseInfo)
684 struct zebDatabaseInfoB *zdi = *zdip;
688 zei->updateHandle = update_handle;
690 if (zdi->attributeDetails)
692 /* remove attribute details keys and delete it */
693 zebAttributeDetails zad = zdi->attributeDetails;
695 rec = rec_get(zei->records, zad->sysno);
696 (*zei->updateFunc)(zei->updateHandle, rec, 0);
699 /* remove database record keys and delete it */
700 rec = rec_get (zei->records, zdi->sysno);
701 (*zei->updateFunc)(zei->updateHandle, rec, 0);
704 /* remove from list */
707 /* current database is IR-Explain-1 */
710 zdip = &(*zdip)->next;
715 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
717 struct zebDatabaseInfoB *zdi;
718 const char *database_n = strrchr (database, '/');
723 database_n = database;
726 if (zei->curDatabaseInfo &&
727 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
729 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
731 if (!STRCASECMP (zdi->databaseName, database_n))
737 yaz_log (YLOG_LOG, "zebraExplain_curDatabase: %s", database);
742 yaz_log (YLOG_LOG, "zebraExplain_readDatabase: %s", database);
744 zebraExplain_readDatabase (zei, zdi);
746 if (zdi->attributeDetails->readFlag)
749 yaz_log (YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
751 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
753 zei->curDatabaseInfo = zdi;
757 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
759 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
760 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
761 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
762 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
765 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
767 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
769 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
773 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
775 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
776 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
777 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
780 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
781 zebAccessInfo accessInfo)
783 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
789 data1_pr_tree (zei->dh, n, stdout);
794 if ((p = accessInfo->attributeSetIds))
796 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
797 for (; p; p = p->next)
798 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
800 if ((p = accessInfo->schemas))
802 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
803 for (; p; p = p->next)
804 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
808 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
809 int explain_database)
811 struct zebDatabaseInfoB *zdi;
812 data1_node *node_dbinfo, *node_adinfo;
813 const char *database_n = strrchr (database, '/');
818 database_n = database;
821 yaz_log (YLOG_LOG, "zebraExplain_newDatabase: %s", database);
824 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
826 if (!STRCASECMP (zdi->databaseName, database_n))
831 /* it's new really. make it */
832 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
833 zdi->next = zei->databaseInfo;
834 zei->databaseInfo = zdi;
836 zdi->recordCount = 0;
837 zdi->recordBytes = 0;
839 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
841 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
846 zdi->data1_database =
847 data1_read_sgml (zei->dh, zei->nmem,
848 "<explain><databaseInfo>DatabaseInfo\n"
850 if (!zdi->data1_database)
853 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
855 assert (node_dbinfo);
857 zebraExplain_initCommonInfo (zei, node_dbinfo);
858 zebraExplain_initAccessInfo (zei, node_dbinfo);
860 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
861 database, zei->nmem);
863 if (explain_database)
864 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
867 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
870 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
874 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
878 zei->curDatabaseInfo = zdi;
880 zdi->attributeDetails = (zebAttributeDetails)
881 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
882 zdi->attributeDetails->readFlag = 0;
883 zdi->attributeDetails->sysno = 0;
884 zdi->attributeDetails->dirty = 1;
885 zdi->attributeDetails->SUInfo = NULL;
886 zdi->attributeDetails->data1_tree =
887 data1_read_sgml (zei->dh, zei->nmem,
888 "<explain><attributeDetails>AttributeDetails\n"
891 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
892 "/attributeDetails");
893 assert (node_adinfo);
895 zebraExplain_initCommonInfo (zei, node_adinfo);
900 static void writeAttributeValueDetails (ZebraExplainInfo zei,
901 zebAttributeDetails zad,
902 data1_node *node_atvs, data1_attset *attset)
905 struct zebSUInfoB *zsui;
906 int set_ordinal = attset->reference;
907 data1_attset_child *c;
909 for (c = attset->children; c; c = c->next)
910 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
911 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
913 if (zsui->info.which == ZEB_SU_SET_USE &&
914 set_ordinal == zsui->info.u.su.set)
916 data1_node *node_attvalue, *node_value;
917 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
918 0 /* attr */, node_atvs);
919 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
920 0 /* attr */, node_attvalue);
921 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
922 zsui->info.u.su.use, zei->nmem);
927 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
928 struct zebraCategoryListInfo *zcl,
935 data1_node *node_ci, *node_categoryList;
937 static char *category[] = {
949 node_categoryList = zcl->data1_categoryList;
952 yaz_log (YLOG_LOG, "zebraExplain_writeCategoryList");
955 drec = createRecord (zei->records, &sysno);
957 node_ci = data1_search_tag (zei->dh, node_categoryList,
960 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
964 for (i = 0; category[i]; i++)
966 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
967 0 /* attr */, node_ci);
969 data1_mk_tag_data_text (zei->dh, node_cat, "name",
970 category[i], zei->nmem);
972 /* extract *searchable* keys from it. We do this here, because
973 record count, etc. is affected */
975 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
977 /* convert to "SGML" and write it */
979 data1_pr_tree (zei->dh, node_categoryList, stderr);
981 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
982 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
983 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
984 drec->size[recInfo_storeData] = sgml_len;
986 rec_put (zei->records, &drec);
989 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
990 zebAttributeDetails zad,
991 const char *databaseName,
997 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
998 struct zebSUInfoB *zsui;
1006 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeDetails");
1009 drec = createRecord (zei->records, &zad->sysno);
1010 assert (zad->data1_tree);
1012 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
1013 "/attributeDetails");
1014 zebraExplain_updateCommonInfo (zei, node_adinfo);
1016 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
1017 databaseName, zei->nmem);
1019 /* extract *searchable* keys from it. We do this here, because
1020 record count, etc. is affected */
1022 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1024 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
1025 "attributesBySet", node_adinfo);
1029 data1_node *node_asd;
1030 data1_attset *attset;
1031 int set_ordinal = -1;
1032 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1034 if (zsui->info.which == ZEB_SU_SET_USE &&
1035 (set_ordinal < 0 || set_ordinal > zsui->info.u.su.set)
1036 && zsui->info.u.su.set > set_min)
1037 set_ordinal = zsui->info.u.su.set;
1039 if (set_ordinal < 0)
1041 set_min = set_ordinal;
1042 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1043 "attributeSetDetails",
1044 0 /* attr */, node_attributesBySet);
1046 attset = data1_attset_search_id (zei->dh, set_ordinal);
1049 zebraExplain_loadAttsets (zei->dh, zei->res);
1050 attset = data1_attset_search_id (zei->dh, set_ordinal);
1057 oe.proto = PROTO_Z3950;
1058 oe.oclass = CLASS_ATTSET;
1059 oe.value = (enum oid_value) set_ordinal;
1061 if (oid_ent_to_oid (&oe, oid))
1063 data1_node *node_abt, *node_atd, *node_atvs;
1064 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1067 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1069 0 /*attr */, node_asd);
1070 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1071 "attributeTypeDetails",
1072 0 /* attr */, node_abt);
1073 data1_mk_tag_data_int (zei->dh, node_atd,
1074 "type", 1, zei->nmem);
1075 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1077 0 /* attr */, node_atd);
1078 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1082 /* zebra info (private) */
1083 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1084 "zebraInfo", node_adinfo);
1085 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1086 "attrlist", node_zebra);
1087 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1089 struct oident oident;
1091 data1_node *node_attr;
1093 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1095 if (zsui->info.which == ZEB_SU_SET_USE)
1097 oident.proto = PROTO_Z3950;
1098 oident.oclass = CLASS_ATTSET;
1099 oident.value = (enum oid_value) zsui->info.u.su.set;
1100 oid_ent_to_oid (&oident, oid);
1102 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1103 oident.desc, zei->nmem);
1104 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1105 zsui->info.u.su.use, zei->nmem);
1107 else if (zsui->info.which == ZEB_SU_STR)
1109 data1_mk_tag_data_text (zei->dh, node_attr, "str",
1110 zsui->info.u.str, zei->nmem);
1112 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1113 zsui->info.ordinal, zei->nmem);
1115 /* convert to "SGML" and write it */
1117 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1119 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1121 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1122 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1123 drec->size[recInfo_storeData] = sgml_len;
1125 rec_put (zei->records, &drec);
1128 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1129 struct zebDatabaseInfoB *zdi,
1135 data1_node *node_dbinfo, *node_count, *node_zebra;
1142 yaz_log (YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1144 drec = createRecord (zei->records, &zdi->sysno);
1145 assert (zdi->data1_database);
1147 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1150 assert (node_dbinfo);
1151 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1152 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1154 /* extract *searchable* keys from it. We do this here, because
1155 record count, etc. is affected */
1157 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1159 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1160 "recordCount", node_dbinfo);
1161 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1162 zdi->recordCount, zei->nmem);
1164 /* zebra info (private) */
1165 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1166 "zebraInfo", node_dbinfo);
1167 data1_mk_tag_data_zint (zei->dh, node_zebra,
1168 "recordBytes", zdi->recordBytes, zei->nmem);
1169 /* convert to "SGML" and write it */
1171 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1173 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1175 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1176 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1177 drec->size[recInfo_storeData] = sgml_len;
1179 rec_put (zei->records, &drec);
1182 static void writeAttributeValues (ZebraExplainInfo zei,
1183 data1_node *node_values,
1184 data1_attset *attset)
1187 data1_attset_child *c;
1192 for (c = attset->children; c; c = c->next)
1193 writeAttributeValues (zei, node_values, c->child);
1194 for (atts = attset->atts; atts; atts = atts->next)
1196 data1_node *node_value;
1198 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1199 0 /* attr */, node_values);
1200 data1_mk_tag_data_text (zei->dh, node_value, "name",
1201 atts->name, zei->nmem);
1202 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1203 0 /* attr */, node_value);
1204 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1205 atts->value, zei->nmem);
1210 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1217 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1218 data1_node *node_values;
1219 struct oident *entp;
1220 struct data1_attset *attset = NULL;
1222 if ((entp = oid_getentbyoid (o->oid)))
1223 attset = data1_attset_search_id (zei->dh, entp->value);
1226 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1227 attset ? attset->name : "<unknown>");
1230 drec = createRecord (zei->records, &o->sysno);
1232 data1_read_sgml (zei->dh, zei->nmem,
1233 "<explain><attributeSetInfo>AttributeSetInfo\n"
1236 node_attinfo = data1_search_tag (zei->dh, node_root,
1237 "/attributeSetInfo");
1239 assert (node_attinfo);
1240 zebraExplain_initCommonInfo (zei, node_attinfo);
1241 zebraExplain_updateCommonInfo (zei, node_attinfo);
1243 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1244 "oid", o->oid, zei->nmem);
1245 if (attset && attset->name)
1246 data1_mk_tag_data_text (zei->dh, node_attinfo,
1247 "name", attset->name, zei->nmem);
1249 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1250 "attributes", node_attinfo);
1251 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1252 "attributeType", node_attributes);
1253 data1_mk_tag_data_text (zei->dh, node_atttype,
1254 "name", "Use", zei->nmem);
1255 data1_mk_tag_data_text (zei->dh, node_atttype,
1256 "description", "Use Attribute", zei->nmem);
1257 data1_mk_tag_data_int (zei->dh, node_atttype,
1258 "type", 1, zei->nmem);
1259 node_values = data1_mk_tag (zei->dh, zei->nmem,
1260 "attributeValues", 0 /* attr */, node_atttype);
1262 writeAttributeValues (zei, node_values, attset);
1264 /* extract *searchable* keys from it. We do this here, because
1265 record count, etc. is affected */
1267 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1268 /* convert to "SGML" and write it */
1270 data1_pr_tree (zei->dh, node_root, stderr);
1272 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1273 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1274 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1275 drec->size[recInfo_storeData] = sgml_len;
1277 rec_put (zei->records, &drec);
1280 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1282 struct zebDatabaseInfoB *zdi;
1283 data1_node *node_tgtinfo, *node_list, *node_zebra;
1292 trec = rec_get (zei->records, 1);
1293 xfree (trec->info[recInfo_storeData]);
1295 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1297 assert (node_tgtinfo);
1299 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1300 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1302 /* convert to "SGML" and write it */
1304 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1306 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1307 "zebraInfo", node_tgtinfo);
1308 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1309 ZEBRAVER, zei->nmem);
1310 node_list = data1_mk_tag (zei->dh, zei->nmem,
1311 "databaseList", 0 /* attr */, node_zebra);
1312 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1314 data1_node *node_db;
1315 node_db = data1_mk_tag (zei->dh, zei->nmem,
1316 "database", 0 /* attr */, node_list);
1317 data1_mk_tag_data_text (zei->dh, node_db, "name",
1318 zdi->databaseName, zei->nmem);
1319 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1320 zdi->sysno, zei->nmem);
1321 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1322 zdi->attributeDetails->sysno, zei->nmem);
1324 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1325 zei->ordinalSU, zei->nmem);
1327 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1328 zei->runNumber, zei->nmem);
1331 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1333 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1335 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1336 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1337 trec->size[recInfo_storeData] = sgml_len;
1339 rec_put (zei->records, &trec);
1342 int zebraExplain_lookup_attr_su(ZebraExplainInfo zei, int set, int use)
1344 struct zebSUInfoB *zsui;
1346 assert (zei->curDatabaseInfo);
1347 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1348 zsui; zsui=zsui->next)
1349 if (zsui->info.which == ZEB_SU_SET_USE &&
1350 zsui->info.u.su.use == use && zsui->info.u.su.set == set)
1351 return zsui->info.ordinal;
1355 int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, const char *str)
1357 struct zebSUInfoB *zsui;
1359 assert (zei->curDatabaseInfo);
1360 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1361 zsui; zsui=zsui->next)
1362 if (zsui->info.which == ZEB_SU_STR &&
1363 !strcmp(zsui->info.u.str, str))
1364 return zsui->info.ordinal;
1368 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1369 int (*f)(void *handle, int ord))
1371 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1374 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1375 for ( ;zsui; zsui = zsui->next)
1376 (*f)(handle, zsui->info.ordinal);
1381 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1382 const char **db, int *set, int *use)
1384 struct zebDatabaseInfoB *zdb;
1385 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1387 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1388 for ( ;zsui; zsui = zsui->next)
1389 if (zsui->info.which == ZEB_SU_SET_USE &&
1390 zsui->info.ordinal == ord)
1392 *db = zdb->databaseName;
1393 *set = zsui->info.u.su.set;
1394 *use = zsui->info.u.su.use;
1401 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1402 zebAccessObject *op,
1407 for (ao = *op; ao; ao = ao->next)
1408 if (!oid_oidcmp (oid, ao->oid))
1412 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1415 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1422 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1427 oe.proto = PROTO_Z3950;
1428 oe.oclass = CLASS_ATTSET;
1429 oe.value = (enum oid_value) set;
1431 if (oid_ent_to_oid (&oe, oid))
1433 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1434 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1435 accessInfo->attributeSetIds, oid);
1439 int zebraExplain_add_attr_su(ZebraExplainInfo zei, int set, int use)
1441 struct zebSUInfoB *zsui;
1443 assert (zei->curDatabaseInfo);
1444 zebraExplain_addAttributeSet (zei, set);
1445 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1446 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1447 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1448 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1450 zsui->info.which = ZEB_SU_SET_USE;
1451 zsui->info.u.su.set = set;
1452 zsui->info.u.su.use = use;
1453 zsui->info.ordinal = (zei->ordinalSU)++;
1454 return zsui->info.ordinal;
1457 int zebraExplain_add_attr_str(ZebraExplainInfo zei, const char *str)
1459 struct zebSUInfoB *zsui;
1461 assert (zei->curDatabaseInfo);
1462 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1463 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1464 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1465 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1467 zsui->info.which = ZEB_SU_STR;
1468 zsui->info.u.str = nmem_strdup(zei->nmem, str);
1469 zsui->info.ordinal = (zei->ordinalSU)++;
1470 return zsui->info.ordinal;
1473 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1475 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1476 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1477 accessInfo->schemas, oid);
1480 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1482 assert (zei->curDatabaseInfo);
1486 zei->curDatabaseInfo->recordBytes += adjust_num;
1487 zei->curDatabaseInfo->dirty = 1;
1491 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1493 assert (zei->curDatabaseInfo);
1497 zei->curDatabaseInfo->recordCount += adjust_num;
1498 zei->curDatabaseInfo->dirty = 1;
1502 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1508 return zei->runNumber += adjust_num;
1511 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1513 RecordAttr *recordAttr;
1515 if (rec->info[recInfo_attr])
1516 return (RecordAttr *) rec->info[recInfo_attr];
1517 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1518 rec->info[recInfo_attr] = (char *) recordAttr;
1519 rec->size[recInfo_attr] = sizeof(*recordAttr);
1521 recordAttr->recordSize = 0;
1522 recordAttr->recordOffset = 0;
1523 recordAttr->runNumber = zei->runNumber;
1527 static void att_loadset(void *p, const char *n, const char *name)
1529 data1_handle dh = (data1_handle) p;
1530 if (!data1_get_attset (dh, name))
1531 yaz_log (YLOG_WARN, "Directive attset failed for %s", name);
1534 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1536 res_trav(res, "attset", dh, att_loadset);
1540 zebraExplain_addSU adds to AttributeDetails for a database and
1541 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1542 exist for the database.
1544 If the database doesn't exist globally (in TargetInfo) an
1545 AttributeSetInfo must be added (globally).