1 /* $Id: zinfo.c,v 1.44 2005-01-16 23:33:31 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>
41 struct zebSUInfo info;
42 struct zebSUInfoB *next;
45 typedef struct zebAccessObjectB *zebAccessObject;
46 struct zebAccessObjectB {
53 typedef struct zebAccessInfoB *zebAccessInfo;
54 struct zebAccessInfoB {
55 zebAccessObject attributeSetIds;
56 zebAccessObject schemas;
60 struct zebSUInfoB *SUInfo;
64 data1_node *data1_tree;
65 } *zebAttributeDetails;
67 struct zebDatabaseInfoB {
68 zebAttributeDetails attributeDetails;
70 data1_node *data1_database;
71 zint recordCount; /* records in db */
72 zint recordBytes; /* size of records */
73 SYSNO sysno; /* sysno of database info */
74 int readFlag; /* 1: read is needed when referenced; 0 if not */
75 int dirty; /* 1: database is dirty: write is needed */
76 struct zebDatabaseInfoB *next;
77 zebAccessInfo accessInfo;
80 struct zebraExplainAttset {
83 struct zebraExplainAttset *next;
86 struct zebraCategoryListInfo {
89 data1_node *data1_categoryList;
92 struct zebraExplainInfo {
100 struct zebraExplainAttset *attsets;
102 data1_node *data1_target;
103 struct zebraCategoryListInfo *categoryList;
104 struct zebDatabaseInfoB *databaseInfo;
105 struct zebDatabaseInfoB *curDatabaseInfo;
106 zebAccessInfo accessInfo;
107 char date[15]; /* YYYY MMDD HH MM SS */
108 int (*updateFunc)(void *handle, Record drec, data1_node *n);
112 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
113 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
115 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
117 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
120 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
121 struct zebDatabaseInfoB *zdi,
123 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
124 zebAttributeDetails zad,
125 const char *databaseName,
127 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
128 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
131 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
132 struct zebraCategoryListInfo *zcl,
136 static Record createRecord (Records records, SYSNO *sysno)
141 rec = rec_get (records, *sysno);
142 xfree (rec->info[recInfo_storeData]);
146 rec = rec_new (records);
149 rec->info[recInfo_fileType] =
150 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
151 rec->info[recInfo_databaseName] =
152 rec_strdup ("IR-Explain-1",
153 &rec->size[recInfo_databaseName]);
158 void zebraExplain_flush (ZebraExplainInfo zei, void *handle)
162 zei->updateHandle = handle;
165 struct zebDatabaseInfoB *zdi;
168 /* write each database info record */
169 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
171 zebraExplain_writeDatabase (zei, zdi, 1);
172 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
173 zdi->databaseName, 1);
175 zebraExplain_writeTarget (zei, 1);
176 zebraExplain_writeCategoryList (zei,
179 assert (zei->accessInfo);
180 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
182 zebraExplain_writeAttributeSet (zei, o, 1);
183 for (o = zei->accessInfo->schemas; o; o = o->next)
186 /* zebraExplain_writeSchema (zei, o, 1); */
189 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
191 zebraExplain_writeDatabase (zei, zdi, 0);
192 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
193 zdi->databaseName, 0);
195 zebraExplain_writeTarget (zei, 0);
199 void zebraExplain_close (ZebraExplainInfo zei)
202 yaz_log (YLOG_LOG, "zebraExplain_close");
206 zebraExplain_flush (zei, zei->updateHandle);
207 nmem_destroy (zei->nmem);
210 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
215 for (np = n->child; np; np = np->next)
222 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
224 len = np->child->u.data.len;
227 memcpy (str, np->child->u.data.data, len);
230 oid = odr_getoidbystr_nmem (zei->nmem, str);
232 for (ao = *op; ao; ao = ao->next)
233 if (!oid_oidcmp (oid, ao->oid))
240 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
250 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
251 zebAccessInfo *accessInfo)
257 *accessInfo = (zebAccessInfo)
258 nmem_malloc (zei->nmem, sizeof(**accessInfo));
259 (*accessInfo)->attributeSetIds = NULL;
260 (*accessInfo)->schemas = NULL;
264 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
266 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
267 zebraExplain_mergeOids (zei, np,
268 &(*accessInfo)->attributeSetIds);
269 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
270 zebraExplain_mergeOids (zei, np,
271 &(*accessInfo)->schemas);
280 databaseList (list of databases)
285 targetInfo: TargetInfo
292 dateAdded: 20030630190601
293 dateChanged: 20030630190601
299 oid: 1.2.840.10003.3.2
300 oid: 1.2.840.10003.3.5
301 oid: 1.2.840.10003.3.1
303 oid: 1.2.840.10003.13.1000.81.2
304 oid: 1.2.840.10003.13.2
311 attributeDetailsId: 51
315 attributeDetailsId: 53
318 nextResultSetPosition = 2
321 ZebraExplainInfo zebraExplain_open (
322 Records records, data1_handle dh,
326 int (*updateFunc)(void *handle, Record drec, data1_node *n))
329 ZebraExplainInfo zei;
330 struct zebDatabaseInfoB **zdip;
333 NMEM nmem = nmem_create ();
336 yaz_log (YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
338 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
339 zei->write_flag = writeFlag;
340 zei->updateHandle = updateHandle;
341 zei->updateFunc = updateFunc;
343 zei->curDatabaseInfo = NULL;
344 zei->records = records;
349 zei->categoryList = (struct zebraCategoryListInfo *)
350 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
351 zei->categoryList->sysno = 0;
352 zei->categoryList->dirty = 0;
353 zei->categoryList->data1_categoryList = NULL;
355 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
358 tm = localtime (&our_time);
359 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
360 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
361 tm->tm_hour, tm->tm_min, tm->tm_sec);
363 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
366 zdip = &zei->databaseInfo;
367 trec = rec_get (records, 1); /* get "root" record */
372 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
373 if (trec) /* targetInfo already exists ... */
375 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
377 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
379 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
381 if (!zei->data1_target)
384 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
385 nmem_destroy (zei->nmem);
389 data1_pr_tree (zei->dh, zei->data1_target, stderr);
391 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
393 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
396 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
401 node_list = data1_search_tag (zei->dh, node_zebra->child,
404 np = node_list->child;
406 for (; np; np = np->next)
408 data1_node *node_name = NULL;
409 data1_node *node_id = NULL;
410 data1_node *node_aid = NULL;
412 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
414 for (np2 = np->child; np2; np2 = np2->next)
416 if (np2->which != DATA1N_tag)
418 if (!strcmp (np2->u.tag.tag, "name"))
419 node_name = np2->child;
420 else if (!strcmp (np2->u.tag.tag, "id"))
421 node_id = np2->child;
422 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
423 node_aid = np2->child;
425 assert (node_id && node_name && node_aid);
427 *zdip = (struct zebDatabaseInfoB *)
428 nmem_malloc (zei->nmem, sizeof(**zdip));
429 (*zdip)->readFlag = 1;
431 (*zdip)->data1_database = NULL;
432 (*zdip)->recordCount = 0;
433 (*zdip)->recordBytes = 0;
434 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
436 (*zdip)->databaseName = (char *)
437 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
438 memcpy ((*zdip)->databaseName, node_name->u.data.data,
439 node_name->u.data.len);
440 (*zdip)->databaseName[node_name->u.data.len] = '\0';
441 (*zdip)->sysno = atoi_zn (node_id->u.data.data,
442 node_id->u.data.len);
443 (*zdip)->attributeDetails = (zebAttributeDetails)
444 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
445 (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
446 node_aid->u.data.len);
447 (*zdip)->attributeDetails->readFlag = 1;
448 (*zdip)->attributeDetails->dirty = 0;
449 (*zdip)->attributeDetails->SUInfo = NULL;
451 zdip = &(*zdip)->next;
455 np = data1_search_tag (zei->dh, node_zebra->child,
458 assert (np && np->which == DATA1N_data);
459 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
461 np = data1_search_tag (zei->dh, node_zebra->child,
464 assert (np && np->which == DATA1N_data);
465 zei->runNumber = atoi_zn (np->u.data.data, np->u.data.len);
466 yaz_log (YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
471 else /* create initial targetInfo */
473 data1_node *node_tgtinfo;
482 data1_read_sgml (zei->dh, zei->nmem,
483 "<explain><targetInfo>TargetInfo\n"
485 "<namedResultSets>1</>\n"
486 "<multipleDBSearch>1</>\n"
487 "<nicknames><name>Zebra</></>\n"
489 if (!zei->data1_target)
491 yaz_log (YLOG_FATAL, "Explain schema missing. Check profilePath");
492 nmem_destroy (zei->nmem);
495 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
497 assert (node_tgtinfo);
499 zebraExplain_initCommonInfo (zei, node_tgtinfo);
500 zebraExplain_initAccessInfo (zei, node_tgtinfo);
502 /* write now because we want to be sure about the sysno */
503 trec = rec_new (records);
504 trec->info[recInfo_fileType] =
505 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
506 trec->info[recInfo_databaseName] =
507 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
509 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
510 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
511 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
512 trec->size[recInfo_storeData] = sgml_len;
514 rec_put (records, &trec);
518 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
520 if (!zei->categoryList->dirty)
522 struct zebraCategoryListInfo *zcl = zei->categoryList;
526 zcl->data1_categoryList =
527 data1_read_sgml (zei->dh, zei->nmem,
528 "<explain><categoryList>CategoryList\n"
531 if (zcl->data1_categoryList)
533 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
536 zebraExplain_initCommonInfo (zei, node_cl);
543 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
544 zebAttributeDetails zad)
547 struct zebSUInfoB **zsuip = &zad->SUInfo;
548 data1_node *node_adinfo, *node_zebra, *node_list, *np;
551 rec = rec_get (zei->records, zad->sysno);
553 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
555 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
556 "/attributeDetails");
557 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
559 node_list = data1_search_tag (zei->dh, node_zebra->child,
561 for (np = node_list->child; np; np = np->next)
563 data1_node *node_set = NULL;
564 data1_node *node_use = NULL;
565 data1_node *node_ordinal = NULL;
570 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
572 for (np2 = np->child; np2; np2 = np2->next)
574 if (np2->which != DATA1N_tag || !np2->child ||
575 np2->child->which != DATA1N_data)
577 if (!strcmp (np2->u.tag.tag, "set"))
578 node_set = np2->child;
579 else if (!strcmp (np2->u.tag.tag, "use"))
580 node_use = np2->child;
581 else if (!strcmp (np2->u.tag.tag, "ordinal"))
582 node_ordinal = np2->child;
584 assert (node_set && node_use && node_ordinal);
586 oid_str_len = node_set->u.data.len;
587 if (oid_str_len >= (int) sizeof(oid_str))
588 oid_str_len = sizeof(oid_str)-1;
589 memcpy (oid_str, node_set->u.data.data, oid_str_len);
590 oid_str[oid_str_len] = '\0';
592 *zsuip = (struct zebSUInfoB *)
593 nmem_malloc (zei->nmem, sizeof(**zsuip));
594 (*zsuip)->info.set = oid_getvalbyname (oid_str);
596 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
597 node_use->u.data.len);
598 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
599 node_ordinal->u.data.len);
600 yaz_log (YLOG_DEBUG, "set=%d use=%d ordinal=%d",
601 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
602 zsuip = &(*zsuip)->next;
609 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
610 struct zebDatabaseInfoB *zdi)
613 data1_node *node_dbinfo, *node_zebra, *np;
616 rec = rec_get (zei->records, zdi->sysno);
618 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
620 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
622 assert (node_dbinfo);
623 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
625 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
628 && (np = data1_search_tag (zei->dh, node_zebra->child,
630 && np->child && np->child->which == DATA1N_data)
631 zdi->recordBytes = atoi_zn (np->child->u.data.data,
632 np->child->u.data.len);
633 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
635 (np = data1_search_tag (zei->dh, np->child,
636 "recordCountActual")) &&
637 np->child->which == DATA1N_data)
639 zdi->recordCount = atoi_zn (np->child->u.data.data,
640 np->child->u.data.len);
646 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
648 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
652 if (*zdip == zei->curDatabaseInfo)
654 struct zebDatabaseInfoB *zdi = *zdip;
658 zei->updateHandle = update_handle;
660 if (zdi->attributeDetails)
662 /* remove attribute details keys and delete it */
663 zebAttributeDetails zad = zdi->attributeDetails;
665 rec = rec_get(zei->records, zad->sysno);
666 (*zei->updateFunc)(zei->updateHandle, rec, 0);
669 /* remove database record keys and delete it */
670 rec = rec_get (zei->records, zdi->sysno);
671 (*zei->updateFunc)(zei->updateHandle, rec, 0);
674 /* remove from list */
677 /* current database is IR-Explain-1 */
680 zdip = &(*zdip)->next;
685 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
687 struct zebDatabaseInfoB *zdi;
688 const char *database_n = strrchr (database, '/');
693 database_n = database;
696 if (zei->curDatabaseInfo &&
697 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
699 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
701 if (!STRCASECMP (zdi->databaseName, database_n))
707 yaz_log (YLOG_LOG, "zebraExplain_curDatabase: %s", database);
712 yaz_log (YLOG_LOG, "zebraExplain_readDatabase: %s", database);
714 zebraExplain_readDatabase (zei, zdi);
716 if (zdi->attributeDetails->readFlag)
719 yaz_log (YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
721 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
723 zei->curDatabaseInfo = zdi;
727 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
729 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
730 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
731 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
732 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
735 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
737 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
739 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
743 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
745 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
746 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
747 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
750 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
751 zebAccessInfo accessInfo)
753 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
759 data1_pr_tree (zei->dh, n, stdout);
764 if ((p = accessInfo->attributeSetIds))
766 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
767 for (; p; p = p->next)
768 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
770 if ((p = accessInfo->schemas))
772 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
773 for (; p; p = p->next)
774 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
778 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
779 int explain_database)
781 struct zebDatabaseInfoB *zdi;
782 data1_node *node_dbinfo, *node_adinfo;
783 const char *database_n = strrchr (database, '/');
788 database_n = database;
791 yaz_log (YLOG_LOG, "zebraExplain_newDatabase: %s", database);
794 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
796 if (!STRCASECMP (zdi->databaseName, database_n))
801 /* it's new really. make it */
802 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
803 zdi->next = zei->databaseInfo;
804 zei->databaseInfo = zdi;
806 zdi->recordCount = 0;
807 zdi->recordBytes = 0;
809 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
811 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
816 zdi->data1_database =
817 data1_read_sgml (zei->dh, zei->nmem,
818 "<explain><databaseInfo>DatabaseInfo\n"
820 if (!zdi->data1_database)
823 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
825 assert (node_dbinfo);
827 zebraExplain_initCommonInfo (zei, node_dbinfo);
828 zebraExplain_initAccessInfo (zei, node_dbinfo);
830 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
831 database, zei->nmem);
833 if (explain_database)
834 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
837 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
840 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
844 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
848 zei->curDatabaseInfo = zdi;
850 zdi->attributeDetails = (zebAttributeDetails)
851 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
852 zdi->attributeDetails->readFlag = 0;
853 zdi->attributeDetails->sysno = 0;
854 zdi->attributeDetails->dirty = 1;
855 zdi->attributeDetails->SUInfo = NULL;
856 zdi->attributeDetails->data1_tree =
857 data1_read_sgml (zei->dh, zei->nmem,
858 "<explain><attributeDetails>AttributeDetails\n"
861 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
862 "/attributeDetails");
863 assert (node_adinfo);
865 zebraExplain_initCommonInfo (zei, node_adinfo);
870 static void writeAttributeValueDetails (ZebraExplainInfo zei,
871 zebAttributeDetails zad,
872 data1_node *node_atvs, data1_attset *attset)
875 struct zebSUInfoB *zsui;
876 int set_ordinal = attset->reference;
877 data1_attset_child *c;
879 for (c = attset->children; c; c = c->next)
880 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
881 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
883 data1_node *node_attvalue, *node_value;
884 if (set_ordinal != zsui->info.set)
886 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
887 0 /* attr */, node_atvs);
888 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
889 0 /* attr */, node_attvalue);
890 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
891 zsui->info.use, zei->nmem);
895 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
896 struct zebraCategoryListInfo *zcl,
903 data1_node *node_ci, *node_categoryList;
905 static char *category[] = {
917 node_categoryList = zcl->data1_categoryList;
920 yaz_log (YLOG_LOG, "zebraExplain_writeCategoryList");
923 drec = createRecord (zei->records, &sysno);
925 node_ci = data1_search_tag (zei->dh, node_categoryList,
928 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
932 for (i = 0; category[i]; i++)
934 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
935 0 /* attr */, node_ci);
937 data1_mk_tag_data_text (zei->dh, node_cat, "name",
938 category[i], zei->nmem);
940 /* extract *searchable* keys from it. We do this here, because
941 record count, etc. is affected */
943 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
945 /* convert to "SGML" and write it */
947 data1_pr_tree (zei->dh, node_categoryList, stderr);
949 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
950 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
951 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
952 drec->size[recInfo_storeData] = sgml_len;
954 rec_put (zei->records, &drec);
957 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
958 zebAttributeDetails zad,
959 const char *databaseName,
965 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
966 struct zebSUInfoB *zsui;
974 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeDetails");
977 drec = createRecord (zei->records, &zad->sysno);
978 assert (zad->data1_tree);
980 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
981 "/attributeDetails");
982 zebraExplain_updateCommonInfo (zei, node_adinfo);
984 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
985 databaseName, zei->nmem);
987 /* extract *searchable* keys from it. We do this here, because
988 record count, etc. is affected */
990 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
992 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
993 "attributesBySet", node_adinfo);
997 data1_node *node_asd;
998 data1_attset *attset;
999 int set_ordinal = -1;
1000 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1002 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1003 && zsui->info.set > set_min)
1004 set_ordinal = zsui->info.set;
1006 if (set_ordinal < 0)
1008 set_min = set_ordinal;
1009 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1010 "attributeSetDetails",
1011 0 /* attr */, node_attributesBySet);
1013 attset = data1_attset_search_id (zei->dh, set_ordinal);
1016 zebraExplain_loadAttsets (zei->dh, zei->res);
1017 attset = data1_attset_search_id (zei->dh, set_ordinal);
1024 oe.proto = PROTO_Z3950;
1025 oe.oclass = CLASS_ATTSET;
1026 oe.value = (enum oid_value) set_ordinal;
1028 if (oid_ent_to_oid (&oe, oid))
1030 data1_node *node_abt, *node_atd, *node_atvs;
1031 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1034 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1036 0 /*attr */, node_asd);
1037 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1038 "attributeTypeDetails",
1039 0 /* attr */, node_abt);
1040 data1_mk_tag_data_int (zei->dh, node_atd,
1041 "type", 1, zei->nmem);
1042 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1044 0 /* attr */, node_atd);
1045 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1049 /* zebra info (private) */
1050 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1051 "zebraInfo", node_adinfo);
1052 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1053 "attrlist", node_zebra);
1054 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1056 struct oident oident;
1058 data1_node *node_attr;
1060 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1063 oident.proto = PROTO_Z3950;
1064 oident.oclass = CLASS_ATTSET;
1065 oident.value = (enum oid_value) zsui->info.set;
1066 oid_ent_to_oid (&oident, oid);
1068 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1069 oident.desc, zei->nmem);
1070 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1071 zsui->info.use, zei->nmem);
1072 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1073 zsui->info.ordinal, zei->nmem);
1075 /* convert to "SGML" and write it */
1077 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1079 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1081 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1082 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1083 drec->size[recInfo_storeData] = sgml_len;
1085 rec_put (zei->records, &drec);
1088 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1089 struct zebDatabaseInfoB *zdi,
1095 data1_node *node_dbinfo, *node_count, *node_zebra;
1102 yaz_log (YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1104 drec = createRecord (zei->records, &zdi->sysno);
1105 assert (zdi->data1_database);
1107 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1110 assert (node_dbinfo);
1111 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1112 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1114 /* extract *searchable* keys from it. We do this here, because
1115 record count, etc. is affected */
1117 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1119 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1120 "recordCount", node_dbinfo);
1121 data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
1122 zdi->recordCount, zei->nmem);
1124 /* zebra info (private) */
1125 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1126 "zebraInfo", node_dbinfo);
1127 data1_mk_tag_data_zint (zei->dh, node_zebra,
1128 "recordBytes", zdi->recordBytes, zei->nmem);
1129 /* convert to "SGML" and write it */
1131 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1133 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1135 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1136 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1137 drec->size[recInfo_storeData] = sgml_len;
1139 rec_put (zei->records, &drec);
1142 static void writeAttributeValues (ZebraExplainInfo zei,
1143 data1_node *node_values,
1144 data1_attset *attset)
1147 data1_attset_child *c;
1152 for (c = attset->children; c; c = c->next)
1153 writeAttributeValues (zei, node_values, c->child);
1154 for (atts = attset->atts; atts; atts = atts->next)
1156 data1_node *node_value;
1158 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1159 0 /* attr */, node_values);
1160 data1_mk_tag_data_text (zei->dh, node_value, "name",
1161 atts->name, zei->nmem);
1162 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1163 0 /* attr */, node_value);
1164 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1165 atts->value, zei->nmem);
1170 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1177 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1178 data1_node *node_values;
1179 struct oident *entp;
1180 struct data1_attset *attset = NULL;
1182 if ((entp = oid_getentbyoid (o->oid)))
1183 attset = data1_attset_search_id (zei->dh, entp->value);
1186 yaz_log (YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1187 attset ? attset->name : "<unknown>");
1190 drec = createRecord (zei->records, &o->sysno);
1192 data1_read_sgml (zei->dh, zei->nmem,
1193 "<explain><attributeSetInfo>AttributeSetInfo\n"
1196 node_attinfo = data1_search_tag (zei->dh, node_root,
1197 "/attributeSetInfo");
1199 assert (node_attinfo);
1200 zebraExplain_initCommonInfo (zei, node_attinfo);
1201 zebraExplain_updateCommonInfo (zei, node_attinfo);
1203 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1204 "oid", o->oid, zei->nmem);
1205 if (attset && attset->name)
1206 data1_mk_tag_data_text (zei->dh, node_attinfo,
1207 "name", attset->name, zei->nmem);
1209 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1210 "attributes", node_attinfo);
1211 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1212 "attributeType", node_attributes);
1213 data1_mk_tag_data_text (zei->dh, node_atttype,
1214 "name", "Use", zei->nmem);
1215 data1_mk_tag_data_text (zei->dh, node_atttype,
1216 "description", "Use Attribute", zei->nmem);
1217 data1_mk_tag_data_int (zei->dh, node_atttype,
1218 "type", 1, zei->nmem);
1219 node_values = data1_mk_tag (zei->dh, zei->nmem,
1220 "attributeValues", 0 /* attr */, node_atttype);
1222 writeAttributeValues (zei, node_values, attset);
1224 /* extract *searchable* keys from it. We do this here, because
1225 record count, etc. is affected */
1227 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1228 /* convert to "SGML" and write it */
1230 data1_pr_tree (zei->dh, node_root, stderr);
1232 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1233 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1234 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1235 drec->size[recInfo_storeData] = sgml_len;
1237 rec_put (zei->records, &drec);
1240 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1242 struct zebDatabaseInfoB *zdi;
1243 data1_node *node_tgtinfo, *node_list, *node_zebra;
1252 trec = rec_get (zei->records, 1);
1253 xfree (trec->info[recInfo_storeData]);
1255 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1257 assert (node_tgtinfo);
1259 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1260 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1262 /* convert to "SGML" and write it */
1264 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1266 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1267 "zebraInfo", node_tgtinfo);
1268 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1269 ZEBRAVER, zei->nmem);
1270 node_list = data1_mk_tag (zei->dh, zei->nmem,
1271 "databaseList", 0 /* attr */, node_zebra);
1272 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1274 data1_node *node_db;
1275 node_db = data1_mk_tag (zei->dh, zei->nmem,
1276 "database", 0 /* attr */, node_list);
1277 data1_mk_tag_data_text (zei->dh, node_db, "name",
1278 zdi->databaseName, zei->nmem);
1279 data1_mk_tag_data_zint (zei->dh, node_db, "id",
1280 zdi->sysno, zei->nmem);
1281 data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
1282 zdi->attributeDetails->sysno, zei->nmem);
1284 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1285 zei->ordinalSU, zei->nmem);
1287 data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
1288 zei->runNumber, zei->nmem);
1291 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1293 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1295 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1296 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1297 trec->size[recInfo_storeData] = sgml_len;
1299 rec_put (zei->records, &trec);
1302 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1304 struct zebSUInfoB *zsui;
1306 assert (zei->curDatabaseInfo);
1307 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1308 zsui; zsui=zsui->next)
1309 if (zsui->info.use == use && zsui->info.set == set)
1310 return zsui->info.ordinal;
1314 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1315 int (*f)(void *handle, int ord))
1317 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1320 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1321 for ( ;zsui; zsui = zsui->next)
1322 (*f)(handle, zsui->info.ordinal);
1327 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1328 const char **db, int *set, int *use)
1330 struct zebDatabaseInfoB *zdb;
1331 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1333 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1334 for ( ;zsui; zsui = zsui->next)
1335 if (zsui->info.ordinal == ord)
1337 *db = zdb->databaseName;
1338 *set = zsui->info.set;
1339 *use = zsui->info.use;
1346 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1347 zebAccessObject *op,
1352 for (ao = *op; ao; ao = ao->next)
1353 if (!oid_oidcmp (oid, ao->oid))
1357 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1360 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1367 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1372 oe.proto = PROTO_Z3950;
1373 oe.oclass = CLASS_ATTSET;
1374 oe.value = (enum oid_value) set;
1376 if (oid_ent_to_oid (&oe, oid))
1378 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1379 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1380 accessInfo->attributeSetIds, oid);
1384 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1386 struct zebSUInfoB *zsui;
1388 assert (zei->curDatabaseInfo);
1389 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1390 zsui; zsui=zsui->next)
1391 if (zsui->info.use == use && zsui->info.set == set)
1393 zebraExplain_addAttributeSet (zei, set);
1394 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1395 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1396 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1397 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1399 zsui->info.set = set;
1400 zsui->info.use = use;
1401 zsui->info.ordinal = (zei->ordinalSU)++;
1402 return zsui->info.ordinal;
1405 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1407 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1408 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1409 accessInfo->schemas, oid);
1412 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1414 assert (zei->curDatabaseInfo);
1418 zei->curDatabaseInfo->recordBytes += adjust_num;
1419 zei->curDatabaseInfo->dirty = 1;
1423 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1425 assert (zei->curDatabaseInfo);
1429 zei->curDatabaseInfo->recordCount += adjust_num;
1430 zei->curDatabaseInfo->dirty = 1;
1434 zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1440 return zei->runNumber += adjust_num;
1443 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1445 RecordAttr *recordAttr;
1447 if (rec->info[recInfo_attr])
1448 return (RecordAttr *) rec->info[recInfo_attr];
1449 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1450 rec->info[recInfo_attr] = (char *) recordAttr;
1451 rec->size[recInfo_attr] = sizeof(*recordAttr);
1453 recordAttr->recordSize = 0;
1454 recordAttr->recordOffset = 0;
1455 recordAttr->runNumber = zei->runNumber;
1459 static void att_loadset(void *p, const char *n, const char *name)
1461 data1_handle dh = (data1_handle) p;
1462 if (!data1_get_attset (dh, name))
1463 yaz_log (YLOG_WARN, "Directive attset failed for %s", name);
1466 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1468 res_trav(res, "attset", dh, att_loadset);
1472 zebraExplain_addSU adds to AttributeDetails for a database and
1473 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1474 exist for the database.
1476 If the database doesn't exist globally (in TargetInfo) an
1477 AttributeSetInfo must be added (globally).