1 /* $Id: zinfo.c,v 1.37.2.4 2006-08-14 10:39:00 adam Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003
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 this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <sys/types.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 int recordCount; /* records in db */
72 int recordBytes; /* size of records */
73 int 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, int *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 (LOG_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 logf (LOG_LOG, "zebraExplain_open wr=%d", writeFlag);
338 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
339 zei->databaseInfo = 0;
340 zei->write_flag = writeFlag;
341 zei->updateHandle = updateHandle;
342 zei->updateFunc = updateFunc;
344 zei->curDatabaseInfo = NULL;
345 zei->records = records;
350 zei->categoryList = (struct zebraCategoryListInfo *)
351 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
352 zei->categoryList->sysno = 0;
353 zei->categoryList->dirty = 0;
354 zei->categoryList->data1_categoryList = NULL;
356 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
359 tm = localtime (&our_time);
360 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
361 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
362 tm->tm_hour, tm->tm_min, tm->tm_sec);
364 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
367 zdip = &zei->databaseInfo;
368 trec = rec_get (records, 1); /* get "root" record */
373 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
374 if (trec) /* targetInfo already exists ... */
376 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
378 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
380 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
382 if (!zei->data1_target)
385 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
386 nmem_destroy (zei->nmem);
390 data1_pr_tree (zei->dh, zei->data1_target, stderr);
392 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
394 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
397 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
402 node_list = data1_search_tag (zei->dh, node_zebra->child,
405 np = node_list->child;
407 for (; np; np = np->next)
409 data1_node *node_name = NULL;
410 data1_node *node_id = NULL;
411 data1_node *node_aid = NULL;
413 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
415 for (np2 = np->child; np2; np2 = np2->next)
417 if (np2->which != DATA1N_tag)
419 if (!strcmp (np2->u.tag.tag, "name"))
420 node_name = np2->child;
421 else if (!strcmp (np2->u.tag.tag, "id"))
422 node_id = np2->child;
423 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
424 node_aid = np2->child;
426 assert (node_id && node_name && node_aid);
428 *zdip = (struct zebDatabaseInfoB *)
429 nmem_malloc (zei->nmem, sizeof(**zdip));
430 (*zdip)->readFlag = 1;
432 (*zdip)->data1_database = NULL;
433 (*zdip)->recordCount = 0;
434 (*zdip)->recordBytes = 0;
435 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
437 (*zdip)->databaseName = (char *)
438 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
439 memcpy ((*zdip)->databaseName, node_name->u.data.data,
440 node_name->u.data.len);
441 (*zdip)->databaseName[node_name->u.data.len] = '\0';
442 (*zdip)->sysno = atoi_n (node_id->u.data.data,
443 node_id->u.data.len);
444 (*zdip)->attributeDetails = (zebAttributeDetails)
445 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
446 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
447 node_aid->u.data.len);
448 (*zdip)->attributeDetails->readFlag = 1;
449 (*zdip)->attributeDetails->dirty = 0;
450 (*zdip)->attributeDetails->SUInfo = NULL;
452 zdip = &(*zdip)->next;
456 np = data1_search_tag (zei->dh, node_zebra->child,
459 assert (np && np->which == DATA1N_data);
460 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
462 np = data1_search_tag (zei->dh, node_zebra->child,
465 assert (np && np->which == DATA1N_data);
466 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
467 yaz_log (LOG_DEBUG, "read runnumber = %d", zei->runNumber);
472 else /* create initial targetInfo */
474 data1_node *node_tgtinfo;
483 data1_read_sgml (zei->dh, zei->nmem,
484 "<explain><targetInfo>TargetInfo\n"
486 "<namedResultSets>1</>\n"
487 "<multipleDBSearch>1</>\n"
488 "<nicknames><name>Zebra</></>\n"
490 if (!zei->data1_target)
492 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
493 nmem_destroy (zei->nmem);
496 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
498 assert (node_tgtinfo);
500 zebraExplain_initCommonInfo (zei, node_tgtinfo);
501 zebraExplain_initAccessInfo (zei, node_tgtinfo);
503 /* write now because we want to be sure about the sysno */
504 trec = rec_new (records);
505 trec->info[recInfo_fileType] =
506 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
507 trec->info[recInfo_databaseName] =
508 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
510 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
511 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
512 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
513 trec->size[recInfo_storeData] = sgml_len;
515 rec_put (records, &trec);
519 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
521 if (!zei->categoryList->dirty)
523 struct zebraCategoryListInfo *zcl = zei->categoryList;
527 zcl->data1_categoryList =
528 data1_read_sgml (zei->dh, zei->nmem,
529 "<explain><categoryList>CategoryList\n"
532 if (zcl->data1_categoryList)
534 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
537 zebraExplain_initCommonInfo (zei, node_cl);
544 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
545 zebAttributeDetails zad)
548 struct zebSUInfoB **zsuip = &zad->SUInfo;
549 data1_node *node_adinfo, *node_zebra, *node_list, *np;
552 rec = rec_get (zei->records, zad->sysno);
554 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
556 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
557 "/attributeDetails");
558 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
560 node_list = data1_search_tag (zei->dh, node_zebra->child,
562 for (np = node_list->child; np; np = np->next)
564 data1_node *node_set = NULL;
565 data1_node *node_use = NULL;
566 data1_node *node_ordinal = NULL;
571 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
573 for (np2 = np->child; np2; np2 = np2->next)
575 if (np2->which != DATA1N_tag || !np2->child ||
576 np2->child->which != DATA1N_data)
578 if (!strcmp (np2->u.tag.tag, "set"))
579 node_set = np2->child;
580 else if (!strcmp (np2->u.tag.tag, "use"))
581 node_use = np2->child;
582 else if (!strcmp (np2->u.tag.tag, "ordinal"))
583 node_ordinal = np2->child;
585 assert (node_set && node_use && node_ordinal);
587 oid_str_len = node_set->u.data.len;
588 if (oid_str_len >= (int) sizeof(oid_str))
589 oid_str_len = sizeof(oid_str)-1;
590 memcpy (oid_str, node_set->u.data.data, oid_str_len);
591 oid_str[oid_str_len] = '\0';
593 *zsuip = (struct zebSUInfoB *)
594 nmem_malloc (zei->nmem, sizeof(**zsuip));
595 (*zsuip)->info.set = oid_getvalbyname (oid_str);
597 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
598 node_use->u.data.len);
599 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
600 node_ordinal->u.data.len);
601 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
602 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
603 zsuip = &(*zsuip)->next;
610 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
611 struct zebDatabaseInfoB *zdi)
614 data1_node *node_dbinfo, *node_zebra, *np;
617 rec = rec_get (zei->records, zdi->sysno);
619 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
621 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
623 assert (node_dbinfo);
624 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
626 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
629 && (np = data1_search_tag (zei->dh, node_zebra->child,
631 && np->child && np->child->which == DATA1N_data)
632 zdi->recordBytes = atoi_n (np->child->u.data.data,
633 np->child->u.data.len);
634 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
636 (np = data1_search_tag (zei->dh, np->child,
637 "recordCountActual")) &&
638 np->child->which == DATA1N_data)
640 zdi->recordCount = atoi_n (np->child->u.data.data,
641 np->child->u.data.len);
647 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
649 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
653 if (*zdip == zei->curDatabaseInfo)
655 struct zebDatabaseInfoB *zdi = *zdip;
659 zei->updateHandle = update_handle;
661 if (zdi->attributeDetails)
663 /* remove attribute details keys and delete it */
664 zebAttributeDetails zad = zdi->attributeDetails;
666 rec = rec_get(zei->records, zad->sysno);
667 (*zei->updateFunc)(zei->updateHandle, rec, 0);
670 /* remove database record keys and delete it */
671 rec = rec_get (zei->records, zdi->sysno);
672 (*zei->updateFunc)(zei->updateHandle, rec, 0);
675 /* remove from list */
678 /* current database is IR-Explain-1 */
681 zdip = &(*zdip)->next;
686 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
688 struct zebDatabaseInfoB *zdi;
689 const char *database_n = strrchr (database, '/');
694 database_n = database;
697 if (zei->curDatabaseInfo &&
698 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
700 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
702 if (!STRCASECMP (zdi->databaseName, database_n))
708 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
713 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
715 zebraExplain_readDatabase (zei, zdi);
717 if (zdi->attributeDetails->readFlag)
720 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
722 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
724 zei->curDatabaseInfo = zdi;
728 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
730 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
731 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
732 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
733 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
736 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
738 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
740 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
744 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
746 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
747 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
748 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
751 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
752 zebAccessInfo accessInfo)
754 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
760 data1_pr_tree (zei->dh, n, stdout);
765 if ((p = accessInfo->attributeSetIds))
767 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
768 for (; p; p = p->next)
769 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
771 if ((p = accessInfo->schemas))
773 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
774 for (; p; p = p->next)
775 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
779 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
780 int explain_database)
782 struct zebDatabaseInfoB *zdi;
783 data1_node *node_dbinfo, *node_adinfo;
784 const char *database_n = strrchr (database, '/');
789 database_n = database;
792 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
795 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
797 if (!STRCASECMP (zdi->databaseName, database_n))
802 /* it's new really. make it */
803 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
804 zdi->next = zei->databaseInfo;
805 zei->databaseInfo = zdi;
807 zdi->recordCount = 0;
808 zdi->recordBytes = 0;
810 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
812 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
817 zdi->data1_database =
818 data1_read_sgml (zei->dh, zei->nmem,
819 "<explain><databaseInfo>DatabaseInfo\n"
821 if (!zdi->data1_database)
824 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
826 assert (node_dbinfo);
828 zebraExplain_initCommonInfo (zei, node_dbinfo);
829 zebraExplain_initAccessInfo (zei, node_dbinfo);
831 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
832 database, zei->nmem);
834 if (explain_database)
835 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
838 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
841 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
845 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
849 zei->curDatabaseInfo = zdi;
851 zdi->attributeDetails = (zebAttributeDetails)
852 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
853 zdi->attributeDetails->readFlag = 0;
854 zdi->attributeDetails->sysno = 0;
855 zdi->attributeDetails->dirty = 1;
856 zdi->attributeDetails->SUInfo = NULL;
857 zdi->attributeDetails->data1_tree =
858 data1_read_sgml (zei->dh, zei->nmem,
859 "<explain><attributeDetails>AttributeDetails\n"
862 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
863 "/attributeDetails");
864 assert (node_adinfo);
866 zebraExplain_initCommonInfo (zei, node_adinfo);
871 static void writeAttributeValueDetails (ZebraExplainInfo zei,
872 zebAttributeDetails zad,
873 data1_node *node_atvs, data1_attset *attset)
876 struct zebSUInfoB *zsui;
877 int set_ordinal = attset->reference;
878 data1_attset_child *c;
880 for (c = attset->children; c; c = c->next)
881 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
882 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
884 data1_node *node_attvalue, *node_value;
885 if (set_ordinal != zsui->info.set)
887 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
888 0 /* attr */, node_atvs);
889 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
890 0 /* attr */, node_attvalue);
891 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
892 zsui->info.use, zei->nmem);
896 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
897 struct zebraCategoryListInfo *zcl,
904 data1_node *node_ci, *node_categoryList;
906 static char *category[] = {
918 node_categoryList = zcl->data1_categoryList;
921 logf (LOG_LOG, "zebraExplain_writeCategoryList");
924 drec = createRecord (zei->records, &sysno);
926 node_ci = data1_search_tag (zei->dh, node_categoryList,
929 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
933 for (i = 0; category[i]; i++)
935 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
936 0 /* attr */, node_ci);
938 data1_mk_tag_data_text (zei->dh, node_cat, "name",
939 category[i], zei->nmem);
941 /* extract *searchable* keys from it. We do this here, because
942 record count, etc. is affected */
944 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
946 /* convert to "SGML" and write it */
948 data1_pr_tree (zei->dh, node_categoryList, stderr);
950 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
951 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
952 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
953 drec->size[recInfo_storeData] = sgml_len;
955 rec_put (zei->records, &drec);
958 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
959 zebAttributeDetails zad,
960 const char *databaseName,
966 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
967 struct zebSUInfoB *zsui;
975 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
978 drec = createRecord (zei->records, &zad->sysno);
979 assert (zad->data1_tree);
981 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
982 "/attributeDetails");
983 zebraExplain_updateCommonInfo (zei, node_adinfo);
985 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
986 databaseName, zei->nmem);
988 /* extract *searchable* keys from it. We do this here, because
989 record count, etc. is affected */
991 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
993 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
994 "attributesBySet", node_adinfo);
998 data1_node *node_asd;
999 data1_attset *attset;
1000 int set_ordinal = -1;
1001 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1003 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1004 && zsui->info.set > set_min)
1005 set_ordinal = zsui->info.set;
1007 if (set_ordinal < 0)
1009 set_min = set_ordinal;
1010 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1011 "attributeSetDetails",
1012 0 /* attr */, node_attributesBySet);
1014 attset = data1_attset_search_id (zei->dh, set_ordinal);
1017 zebraExplain_loadAttsets (zei->dh, zei->res);
1018 attset = data1_attset_search_id (zei->dh, set_ordinal);
1025 oe.proto = PROTO_Z3950;
1026 oe.oclass = CLASS_ATTSET;
1027 oe.value = (enum oid_value) set_ordinal;
1029 if (oid_ent_to_oid (&oe, oid))
1031 data1_node *node_abt, *node_atd, *node_atvs;
1032 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1035 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1037 0 /*attr */, node_asd);
1038 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1039 "attributeTypeDetails",
1040 0 /* attr */, node_abt);
1041 data1_mk_tag_data_int (zei->dh, node_atd,
1042 "type", 1, zei->nmem);
1043 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1045 0 /* attr */, node_atd);
1046 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1050 /* zebra info (private) */
1051 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1052 "zebraInfo", node_adinfo);
1053 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1054 "attrlist", node_zebra);
1055 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1057 struct oident oident;
1059 data1_node *node_attr;
1061 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1064 oident.proto = PROTO_Z3950;
1065 oident.oclass = CLASS_ATTSET;
1066 oident.value = (enum oid_value) zsui->info.set;
1067 oid_ent_to_oid (&oident, oid);
1069 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1070 oident.desc, zei->nmem);
1071 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1072 zsui->info.use, zei->nmem);
1073 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1074 zsui->info.ordinal, zei->nmem);
1076 /* convert to "SGML" and write it */
1078 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1080 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1082 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1083 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1084 drec->size[recInfo_storeData] = sgml_len;
1086 rec_put (zei->records, &drec);
1089 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1090 struct zebDatabaseInfoB *zdi,
1096 data1_node *node_dbinfo, *node_count, *node_zebra;
1103 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1105 drec = createRecord (zei->records, &zdi->sysno);
1106 assert (zdi->data1_database);
1108 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1111 assert (node_dbinfo);
1112 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1113 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1115 /* extract *searchable* keys from it. We do this here, because
1116 record count, etc. is affected */
1118 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1120 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1121 "recordCount", node_dbinfo);
1122 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1123 zdi->recordCount, zei->nmem);
1125 /* zebra info (private) */
1126 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1127 "zebraInfo", node_dbinfo);
1128 data1_mk_tag_data_int (zei->dh, node_zebra,
1129 "recordBytes", zdi->recordBytes, zei->nmem);
1130 /* convert to "SGML" and write it */
1132 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1134 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1136 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1137 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1138 drec->size[recInfo_storeData] = sgml_len;
1140 rec_put (zei->records, &drec);
1143 static void writeAttributeValues (ZebraExplainInfo zei,
1144 data1_node *node_values,
1145 data1_attset *attset)
1148 data1_attset_child *c;
1153 for (c = attset->children; c; c = c->next)
1154 writeAttributeValues (zei, node_values, c->child);
1155 for (atts = attset->atts; atts; atts = atts->next)
1157 data1_node *node_value;
1159 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1160 0 /* attr */, node_values);
1161 data1_mk_tag_data_text (zei->dh, node_value, "name",
1162 atts->name, zei->nmem);
1163 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1164 0 /* attr */, node_value);
1165 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1166 atts->value, zei->nmem);
1171 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1178 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1179 data1_node *node_values;
1180 struct oident *entp;
1181 struct data1_attset *attset = NULL;
1183 if ((entp = oid_getentbyoid (o->oid)))
1184 attset = data1_attset_search_id (zei->dh, entp->value);
1187 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1188 attset ? attset->name : "<unknown>");
1191 drec = createRecord (zei->records, &o->sysno);
1193 data1_read_sgml (zei->dh, zei->nmem,
1194 "<explain><attributeSetInfo>AttributeSetInfo\n"
1197 node_attinfo = data1_search_tag (zei->dh, node_root,
1198 "/attributeSetInfo");
1200 assert (node_attinfo);
1201 zebraExplain_initCommonInfo (zei, node_attinfo);
1202 zebraExplain_updateCommonInfo (zei, node_attinfo);
1204 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1205 "oid", o->oid, zei->nmem);
1206 if (attset && attset->name)
1207 data1_mk_tag_data_text (zei->dh, node_attinfo,
1208 "name", attset->name, zei->nmem);
1210 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1211 "attributes", node_attinfo);
1212 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1213 "attributeType", node_attributes);
1214 data1_mk_tag_data_text (zei->dh, node_atttype,
1215 "name", "Use", zei->nmem);
1216 data1_mk_tag_data_text (zei->dh, node_atttype,
1217 "description", "Use Attribute", zei->nmem);
1218 data1_mk_tag_data_int (zei->dh, node_atttype,
1219 "type", 1, zei->nmem);
1220 node_values = data1_mk_tag (zei->dh, zei->nmem,
1221 "attributeValues", 0 /* attr */, node_atttype);
1223 writeAttributeValues (zei, node_values, attset);
1225 /* extract *searchable* keys from it. We do this here, because
1226 record count, etc. is affected */
1228 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1229 /* convert to "SGML" and write it */
1231 data1_pr_tree (zei->dh, node_root, stderr);
1233 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1234 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1235 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1236 drec->size[recInfo_storeData] = sgml_len;
1238 rec_put (zei->records, &drec);
1241 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1243 struct zebDatabaseInfoB *zdi;
1244 data1_node *node_tgtinfo, *node_list, *node_zebra;
1253 trec = rec_get (zei->records, 1);
1254 xfree (trec->info[recInfo_storeData]);
1256 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1258 assert (node_tgtinfo);
1260 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1261 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1263 /* convert to "SGML" and write it */
1265 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1267 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1268 "zebraInfo", node_tgtinfo);
1269 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1270 ZEBRAVER, zei->nmem);
1271 node_list = data1_mk_tag (zei->dh, zei->nmem,
1272 "databaseList", 0 /* attr */, node_zebra);
1273 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1275 data1_node *node_db;
1276 node_db = data1_mk_tag (zei->dh, zei->nmem,
1277 "database", 0 /* attr */, node_list);
1278 data1_mk_tag_data_text (zei->dh, node_db, "name",
1279 zdi->databaseName, zei->nmem);
1280 data1_mk_tag_data_int (zei->dh, node_db, "id",
1281 zdi->sysno, zei->nmem);
1282 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1283 zdi->attributeDetails->sysno, zei->nmem);
1285 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1286 zei->ordinalSU, zei->nmem);
1288 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1289 zei->runNumber, zei->nmem);
1292 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1294 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1296 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1297 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1298 trec->size[recInfo_storeData] = sgml_len;
1300 rec_put (zei->records, &trec);
1303 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1305 struct zebSUInfoB *zsui;
1307 assert (zei->curDatabaseInfo);
1308 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1309 zsui; zsui=zsui->next)
1310 if (zsui->info.use == use && zsui->info.set == set)
1311 return zsui->info.ordinal;
1315 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1316 int (*f)(void *handle, int ord))
1318 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1321 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1322 for ( ;zsui; zsui = zsui->next)
1323 (*f)(handle, zsui->info.ordinal);
1328 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1329 const char **db, int *set, int *use)
1331 struct zebDatabaseInfoB *zdb;
1332 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1334 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1335 for ( ;zsui; zsui = zsui->next)
1336 if (zsui->info.ordinal == ord)
1338 *db = zdb->databaseName;
1339 *set = zsui->info.set;
1340 *use = zsui->info.use;
1347 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1348 zebAccessObject *op,
1353 for (ao = *op; ao; ao = ao->next)
1354 if (!oid_oidcmp (oid, ao->oid))
1358 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1361 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1368 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1373 oe.proto = PROTO_Z3950;
1374 oe.oclass = CLASS_ATTSET;
1375 oe.value = (enum oid_value) set;
1377 if (oid_ent_to_oid (&oe, oid))
1379 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1380 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1381 accessInfo->attributeSetIds, oid);
1385 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1387 struct zebSUInfoB *zsui;
1389 assert (zei->curDatabaseInfo);
1390 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1391 zsui; zsui=zsui->next)
1392 if (zsui->info.use == use && zsui->info.set == set)
1394 zebraExplain_addAttributeSet (zei, set);
1395 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1396 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1397 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1398 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1400 zsui->info.set = set;
1401 zsui->info.use = use;
1402 zsui->info.ordinal = (zei->ordinalSU)++;
1403 return zsui->info.ordinal;
1406 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1408 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1409 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1410 accessInfo->schemas, oid);
1413 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1415 assert (zei->curDatabaseInfo);
1419 zei->curDatabaseInfo->recordBytes += adjust_num;
1420 zei->curDatabaseInfo->dirty = 1;
1424 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1426 assert (zei->curDatabaseInfo);
1430 zei->curDatabaseInfo->recordCount += adjust_num;
1431 zei->curDatabaseInfo->dirty = 1;
1435 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1441 return zei->runNumber += adjust_num;
1444 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1446 RecordAttr *recordAttr;
1448 if (rec->info[recInfo_attr])
1449 return (RecordAttr *) rec->info[recInfo_attr];
1450 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1451 rec->info[recInfo_attr] = (char *) recordAttr;
1452 rec->size[recInfo_attr] = sizeof(*recordAttr);
1454 recordAttr->recordSize = 0;
1455 recordAttr->recordOffset = 0;
1456 recordAttr->runNumber = zei->runNumber;
1460 static void att_loadset(void *p, const char *n, const char *name)
1462 data1_handle dh = (data1_handle) p;
1463 if (!data1_get_attset (dh, name))
1464 logf (LOG_WARN, "Directive attset failed for %s", name);
1467 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1469 res_trav(res, "attset", dh, att_loadset);
1473 zebraExplain_addSU adds to AttributeDetails for a database and
1474 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1475 exist for the database.
1477 If the database doesn't exist globally (in TargetInfo) an
1478 AttributeSetInfo must be added (globally).