1 /* $Id: zinfo.c,v 1.37 2003-06-30 19:37:12 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 Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
40 struct zebSUInfo info;
41 struct zebSUInfoB *next;
44 typedef struct zebAccessObjectB *zebAccessObject;
45 struct zebAccessObjectB {
52 typedef struct zebAccessInfoB *zebAccessInfo;
53 struct zebAccessInfoB {
54 zebAccessObject attributeSetIds;
55 zebAccessObject schemas;
59 struct zebSUInfoB *SUInfo;
63 data1_node *data1_tree;
64 } *zebAttributeDetails;
66 struct zebDatabaseInfoB {
67 zebAttributeDetails attributeDetails;
69 data1_node *data1_database;
70 int recordCount; /* records in db */
71 int recordBytes; /* size of records */
72 int sysno; /* sysno of database info */
73 int readFlag; /* 1: read is needed when referenced; 0 if not */
74 int dirty; /* 1: database is dirty: write is needed */
75 struct zebDatabaseInfoB *next;
76 zebAccessInfo accessInfo;
79 struct zebraExplainAttset {
82 struct zebraExplainAttset *next;
85 struct zebraCategoryListInfo {
88 data1_node *data1_categoryList;
91 struct zebraExplainInfo {
99 struct zebraExplainAttset *attsets;
101 data1_node *data1_target;
102 struct zebraCategoryListInfo *categoryList;
103 struct zebDatabaseInfoB *databaseInfo;
104 struct zebDatabaseInfoB *curDatabaseInfo;
105 zebAccessInfo accessInfo;
106 char date[15]; /* YYYY MMDD HH MM SS */
107 int (*updateFunc)(void *handle, Record drec, data1_node *n);
111 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
112 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
114 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
116 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
119 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
120 struct zebDatabaseInfoB *zdi,
122 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
123 zebAttributeDetails zad,
124 const char *databaseName,
126 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
127 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
130 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
131 struct zebraCategoryListInfo *zcl,
135 static Record createRecord (Records records, int *sysno)
140 rec = rec_get (records, *sysno);
141 xfree (rec->info[recInfo_storeData]);
145 rec = rec_new (records);
148 rec->info[recInfo_fileType] =
149 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
150 rec->info[recInfo_databaseName] =
151 rec_strdup ("IR-Explain-1",
152 &rec->size[recInfo_databaseName]);
157 void zebraExplain_flush (ZebraExplainInfo zei, void *handle)
161 zei->updateHandle = handle;
164 struct zebDatabaseInfoB *zdi;
167 /* write each database info record */
168 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
170 zebraExplain_writeDatabase (zei, zdi, 1);
171 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
172 zdi->databaseName, 1);
174 zebraExplain_writeTarget (zei, 1);
175 zebraExplain_writeCategoryList (zei,
178 assert (zei->accessInfo);
179 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
181 zebraExplain_writeAttributeSet (zei, o, 1);
182 for (o = zei->accessInfo->schemas; o; o = o->next)
185 /* zebraExplain_writeSchema (zei, o, 1); */
188 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
190 zebraExplain_writeDatabase (zei, zdi, 0);
191 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
192 zdi->databaseName, 0);
194 zebraExplain_writeTarget (zei, 0);
198 void zebraExplain_close (ZebraExplainInfo zei)
201 yaz_log (LOG_LOG, "zebraExplain_close");
205 zebraExplain_flush (zei, zei->updateHandle);
206 nmem_destroy (zei->nmem);
209 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
214 for (np = n->child; np; np = np->next)
221 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
223 len = np->child->u.data.len;
226 memcpy (str, np->child->u.data.data, len);
229 oid = odr_getoidbystr_nmem (zei->nmem, str);
231 for (ao = *op; ao; ao = ao->next)
232 if (!oid_oidcmp (oid, ao->oid))
239 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
249 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
250 zebAccessInfo *accessInfo)
256 *accessInfo = (zebAccessInfo)
257 nmem_malloc (zei->nmem, sizeof(**accessInfo));
258 (*accessInfo)->attributeSetIds = NULL;
259 (*accessInfo)->schemas = NULL;
263 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
265 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
266 zebraExplain_mergeOids (zei, np,
267 &(*accessInfo)->attributeSetIds);
268 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
269 zebraExplain_mergeOids (zei, np,
270 &(*accessInfo)->schemas);
279 databaseList (list of databases)
284 targetInfo: TargetInfo
291 dateAdded: 20030630190601
292 dateChanged: 20030630190601
298 oid: 1.2.840.10003.3.2
299 oid: 1.2.840.10003.3.5
300 oid: 1.2.840.10003.3.1
302 oid: 1.2.840.10003.13.1000.81.2
303 oid: 1.2.840.10003.13.2
310 attributeDetailsId: 51
314 attributeDetailsId: 53
317 nextResultSetPosition = 2
320 ZebraExplainInfo zebraExplain_open (
321 Records records, data1_handle dh,
325 int (*updateFunc)(void *handle, Record drec, data1_node *n))
328 ZebraExplainInfo zei;
329 struct zebDatabaseInfoB **zdip;
332 NMEM nmem = nmem_create ();
335 logf (LOG_LOG, "zebraExplain_open wr=%d", writeFlag);
337 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
338 zei->write_flag = writeFlag;
339 zei->updateHandle = updateHandle;
340 zei->updateFunc = updateFunc;
342 zei->curDatabaseInfo = NULL;
343 zei->records = records;
348 zei->categoryList = (struct zebraCategoryListInfo *)
349 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
350 zei->categoryList->sysno = 0;
351 zei->categoryList->dirty = 0;
352 zei->categoryList->data1_categoryList = NULL;
354 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
357 tm = localtime (&our_time);
358 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
359 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
360 tm->tm_hour, tm->tm_min, tm->tm_sec);
362 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
365 zdip = &zei->databaseInfo;
366 trec = rec_get (records, 1); /* get "root" record */
371 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
372 if (trec) /* targetInfo already exists ... */
374 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
376 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
378 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
380 if (!zei->data1_target)
383 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
384 nmem_destroy (zei->nmem);
388 data1_pr_tree (zei->dh, zei->data1_target, stderr);
390 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
392 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
395 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
400 node_list = data1_search_tag (zei->dh, node_zebra->child,
403 np = node_list->child;
405 for (; np; np = np->next)
407 data1_node *node_name = NULL;
408 data1_node *node_id = NULL;
409 data1_node *node_aid = NULL;
411 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
413 for (np2 = np->child; np2; np2 = np2->next)
415 if (np2->which != DATA1N_tag)
417 if (!strcmp (np2->u.tag.tag, "name"))
418 node_name = np2->child;
419 else if (!strcmp (np2->u.tag.tag, "id"))
420 node_id = np2->child;
421 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
422 node_aid = np2->child;
424 assert (node_id && node_name && node_aid);
426 *zdip = (struct zebDatabaseInfoB *)
427 nmem_malloc (zei->nmem, sizeof(**zdip));
428 (*zdip)->readFlag = 1;
430 (*zdip)->data1_database = NULL;
431 (*zdip)->recordCount = 0;
432 (*zdip)->recordBytes = 0;
433 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
435 (*zdip)->databaseName = (char *)
436 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
437 memcpy ((*zdip)->databaseName, node_name->u.data.data,
438 node_name->u.data.len);
439 (*zdip)->databaseName[node_name->u.data.len] = '\0';
440 (*zdip)->sysno = atoi_n (node_id->u.data.data,
441 node_id->u.data.len);
442 (*zdip)->attributeDetails = (zebAttributeDetails)
443 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
444 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
445 node_aid->u.data.len);
446 (*zdip)->attributeDetails->readFlag = 1;
447 (*zdip)->attributeDetails->dirty = 0;
448 (*zdip)->attributeDetails->SUInfo = NULL;
450 zdip = &(*zdip)->next;
454 np = data1_search_tag (zei->dh, node_zebra->child,
457 assert (np && np->which == DATA1N_data);
458 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
460 np = data1_search_tag (zei->dh, node_zebra->child,
463 assert (np && np->which == DATA1N_data);
464 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
465 yaz_log (LOG_DEBUG, "read runnumber = %d", zei->runNumber);
470 else /* create initial targetInfo */
472 data1_node *node_tgtinfo;
481 data1_read_sgml (zei->dh, zei->nmem,
482 "<explain><targetInfo>TargetInfo\n"
484 "<namedResultSets>1</>\n"
485 "<multipleDBSearch>1</>\n"
486 "<nicknames><name>Zebra</></>\n"
488 if (!zei->data1_target)
490 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
491 nmem_destroy (zei->nmem);
494 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
496 assert (node_tgtinfo);
498 zebraExplain_initCommonInfo (zei, node_tgtinfo);
499 zebraExplain_initAccessInfo (zei, node_tgtinfo);
501 /* write now because we want to be sure about the sysno */
502 trec = rec_new (records);
503 trec->info[recInfo_fileType] =
504 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
505 trec->info[recInfo_databaseName] =
506 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
508 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
509 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
510 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
511 trec->size[recInfo_storeData] = sgml_len;
513 rec_put (records, &trec);
517 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
519 if (!zei->categoryList->dirty)
521 struct zebraCategoryListInfo *zcl = zei->categoryList;
525 zcl->data1_categoryList =
526 data1_read_sgml (zei->dh, zei->nmem,
527 "<explain><categoryList>CategoryList\n"
530 if (zcl->data1_categoryList)
532 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
535 zebraExplain_initCommonInfo (zei, node_cl);
542 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
543 zebAttributeDetails zad)
546 struct zebSUInfoB **zsuip = &zad->SUInfo;
547 data1_node *node_adinfo, *node_zebra, *node_list, *np;
550 rec = rec_get (zei->records, zad->sysno);
552 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
554 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
555 "/attributeDetails");
556 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
558 node_list = data1_search_tag (zei->dh, node_zebra->child,
560 for (np = node_list->child; np; np = np->next)
562 data1_node *node_set = NULL;
563 data1_node *node_use = NULL;
564 data1_node *node_ordinal = NULL;
569 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
571 for (np2 = np->child; np2; np2 = np2->next)
573 if (np2->which != DATA1N_tag || !np2->child ||
574 np2->child->which != DATA1N_data)
576 if (!strcmp (np2->u.tag.tag, "set"))
577 node_set = np2->child;
578 else if (!strcmp (np2->u.tag.tag, "use"))
579 node_use = np2->child;
580 else if (!strcmp (np2->u.tag.tag, "ordinal"))
581 node_ordinal = np2->child;
583 assert (node_set && node_use && node_ordinal);
585 oid_str_len = node_set->u.data.len;
586 if (oid_str_len >= (int) sizeof(oid_str))
587 oid_str_len = sizeof(oid_str)-1;
588 memcpy (oid_str, node_set->u.data.data, oid_str_len);
589 oid_str[oid_str_len] = '\0';
591 *zsuip = (struct zebSUInfoB *)
592 nmem_malloc (zei->nmem, sizeof(**zsuip));
593 (*zsuip)->info.set = oid_getvalbyname (oid_str);
595 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
596 node_use->u.data.len);
597 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
598 node_ordinal->u.data.len);
599 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
600 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
601 zsuip = &(*zsuip)->next;
608 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
609 struct zebDatabaseInfoB *zdi)
612 data1_node *node_dbinfo, *node_zebra, *np;
615 rec = rec_get (zei->records, zdi->sysno);
617 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
619 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
621 assert (node_dbinfo);
622 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
624 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
627 && (np = data1_search_tag (zei->dh, node_zebra->child,
629 && np->child && np->child->which == DATA1N_data)
630 zdi->recordBytes = atoi_n (np->child->u.data.data,
631 np->child->u.data.len);
632 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
634 (np = data1_search_tag (zei->dh, np->child,
635 "recordCountActual")) &&
636 np->child->which == DATA1N_data)
638 zdi->recordCount = atoi_n (np->child->u.data.data,
639 np->child->u.data.len);
645 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
647 struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
651 if (*zdip == zei->curDatabaseInfo)
653 struct zebDatabaseInfoB *zdi = *zdip;
657 zei->updateHandle = update_handle;
659 if (zdi->attributeDetails)
661 /* remove attribute details keys and delete it */
662 zebAttributeDetails zad = zdi->attributeDetails;
664 rec = rec_get(zei->records, zad->sysno);
665 (*zei->updateFunc)(zei->updateHandle, rec, 0);
668 /* remove database record keys and delete it */
669 rec = rec_get (zei->records, zdi->sysno);
670 (*zei->updateFunc)(zei->updateHandle, rec, 0);
673 /* remove from list */
676 /* current database is IR-Explain-1 */
679 zdip = &(*zdip)->next;
684 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
686 struct zebDatabaseInfoB *zdi;
687 const char *database_n = strrchr (database, '/');
692 database_n = database;
695 if (zei->curDatabaseInfo &&
696 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
698 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
700 if (!STRCASECMP (zdi->databaseName, database_n))
706 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
711 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
713 zebraExplain_readDatabase (zei, zdi);
715 if (zdi->attributeDetails->readFlag)
718 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
720 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
722 zei->curDatabaseInfo = zdi;
726 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
728 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
729 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
730 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
731 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
734 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
736 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
738 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
742 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
744 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
745 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
746 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
749 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
750 zebAccessInfo accessInfo)
752 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
758 data1_pr_tree (zei->dh, n, stdout);
763 if ((p = accessInfo->attributeSetIds))
765 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
766 for (; p; p = p->next)
767 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
769 if ((p = accessInfo->schemas))
771 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
772 for (; p; p = p->next)
773 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
777 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
778 int explain_database)
780 struct zebDatabaseInfoB *zdi;
781 data1_node *node_dbinfo, *node_adinfo;
782 const char *database_n = strrchr (database, '/');
787 database_n = database;
790 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
793 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
795 if (!STRCASECMP (zdi->databaseName, database_n))
800 /* it's new really. make it */
801 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
802 zdi->next = zei->databaseInfo;
803 zei->databaseInfo = zdi;
805 zdi->recordCount = 0;
806 zdi->recordBytes = 0;
808 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
810 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
815 zdi->data1_database =
816 data1_read_sgml (zei->dh, zei->nmem,
817 "<explain><databaseInfo>DatabaseInfo\n"
819 if (!zdi->data1_database)
822 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
824 assert (node_dbinfo);
826 zebraExplain_initCommonInfo (zei, node_dbinfo);
827 zebraExplain_initAccessInfo (zei, node_dbinfo);
829 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
830 database, zei->nmem);
832 if (explain_database)
833 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
836 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
839 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
843 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
847 zei->curDatabaseInfo = zdi;
849 zdi->attributeDetails = (zebAttributeDetails)
850 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
851 zdi->attributeDetails->readFlag = 0;
852 zdi->attributeDetails->sysno = 0;
853 zdi->attributeDetails->dirty = 1;
854 zdi->attributeDetails->SUInfo = NULL;
855 zdi->attributeDetails->data1_tree =
856 data1_read_sgml (zei->dh, zei->nmem,
857 "<explain><attributeDetails>AttributeDetails\n"
860 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
861 "/attributeDetails");
862 assert (node_adinfo);
864 zebraExplain_initCommonInfo (zei, node_adinfo);
869 static void writeAttributeValueDetails (ZebraExplainInfo zei,
870 zebAttributeDetails zad,
871 data1_node *node_atvs, data1_attset *attset)
874 struct zebSUInfoB *zsui;
875 int set_ordinal = attset->reference;
876 data1_attset_child *c;
878 for (c = attset->children; c; c = c->next)
879 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
880 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
882 data1_node *node_attvalue, *node_value;
883 if (set_ordinal != zsui->info.set)
885 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
886 0 /* attr */, node_atvs);
887 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
888 0 /* attr */, node_attvalue);
889 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
890 zsui->info.use, zei->nmem);
894 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
895 struct zebraCategoryListInfo *zcl,
902 data1_node *node_ci, *node_categoryList;
904 static char *category[] = {
916 node_categoryList = zcl->data1_categoryList;
919 logf (LOG_LOG, "zebraExplain_writeCategoryList");
922 drec = createRecord (zei->records, &sysno);
924 node_ci = data1_search_tag (zei->dh, node_categoryList,
927 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
931 for (i = 0; category[i]; i++)
933 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
934 0 /* attr */, node_ci);
936 data1_mk_tag_data_text (zei->dh, node_cat, "name",
937 category[i], zei->nmem);
939 /* extract *searchable* keys from it. We do this here, because
940 record count, etc. is affected */
942 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
944 /* convert to "SGML" and write it */
946 data1_pr_tree (zei->dh, node_categoryList, stderr);
948 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
949 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
950 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
951 drec->size[recInfo_storeData] = sgml_len;
953 rec_put (zei->records, &drec);
956 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
957 zebAttributeDetails zad,
958 const char *databaseName,
964 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
965 struct zebSUInfoB *zsui;
973 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
976 drec = createRecord (zei->records, &zad->sysno);
977 assert (zad->data1_tree);
979 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
980 "/attributeDetails");
981 zebraExplain_updateCommonInfo (zei, node_adinfo);
983 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
984 databaseName, zei->nmem);
986 /* extract *searchable* keys from it. We do this here, because
987 record count, etc. is affected */
989 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
991 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
992 "attributesBySet", node_adinfo);
996 data1_node *node_asd;
997 data1_attset *attset;
998 int set_ordinal = -1;
999 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1001 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
1002 && zsui->info.set > set_min)
1003 set_ordinal = zsui->info.set;
1005 if (set_ordinal < 0)
1007 set_min = set_ordinal;
1008 node_asd = data1_mk_tag (zei->dh, zei->nmem,
1009 "attributeSetDetails",
1010 0 /* attr */, node_attributesBySet);
1012 attset = data1_attset_search_id (zei->dh, set_ordinal);
1015 zebraExplain_loadAttsets (zei->dh, zei->res);
1016 attset = data1_attset_search_id (zei->dh, set_ordinal);
1023 oe.proto = PROTO_Z3950;
1024 oe.oclass = CLASS_ATTSET;
1025 oe.value = (enum oid_value) set_ordinal;
1027 if (oid_ent_to_oid (&oe, oid))
1029 data1_node *node_abt, *node_atd, *node_atvs;
1030 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
1033 node_abt = data1_mk_tag (zei->dh, zei->nmem,
1035 0 /*attr */, node_asd);
1036 node_atd = data1_mk_tag (zei->dh, zei->nmem,
1037 "attributeTypeDetails",
1038 0 /* attr */, node_abt);
1039 data1_mk_tag_data_int (zei->dh, node_atd,
1040 "type", 1, zei->nmem);
1041 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
1043 0 /* attr */, node_atd);
1044 writeAttributeValueDetails (zei, zad, node_atvs, attset);
1048 /* zebra info (private) */
1049 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1050 "zebraInfo", node_adinfo);
1051 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
1052 "attrlist", node_zebra);
1053 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1055 struct oident oident;
1057 data1_node *node_attr;
1059 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
1062 oident.proto = PROTO_Z3950;
1063 oident.oclass = CLASS_ATTSET;
1064 oident.value = (enum oid_value) zsui->info.set;
1065 oid_ent_to_oid (&oident, oid);
1067 data1_mk_tag_data_text (zei->dh, node_attr, "set",
1068 oident.desc, zei->nmem);
1069 data1_mk_tag_data_int (zei->dh, node_attr, "use",
1070 zsui->info.use, zei->nmem);
1071 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
1072 zsui->info.ordinal, zei->nmem);
1074 /* convert to "SGML" and write it */
1076 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
1078 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1080 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1081 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1082 drec->size[recInfo_storeData] = sgml_len;
1084 rec_put (zei->records, &drec);
1087 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1088 struct zebDatabaseInfoB *zdi,
1094 data1_node *node_dbinfo, *node_count, *node_zebra;
1101 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1103 drec = createRecord (zei->records, &zdi->sysno);
1104 assert (zdi->data1_database);
1106 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1109 assert (node_dbinfo);
1110 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1111 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1113 /* extract *searchable* keys from it. We do this here, because
1114 record count, etc. is affected */
1116 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1118 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1119 "recordCount", node_dbinfo);
1120 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1121 zdi->recordCount, zei->nmem);
1123 /* zebra info (private) */
1124 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1125 "zebraInfo", node_dbinfo);
1126 data1_mk_tag_data_int (zei->dh, node_zebra,
1127 "recordBytes", zdi->recordBytes, zei->nmem);
1128 /* convert to "SGML" and write it */
1130 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1132 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1134 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1135 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1136 drec->size[recInfo_storeData] = sgml_len;
1138 rec_put (zei->records, &drec);
1141 static void writeAttributeValues (ZebraExplainInfo zei,
1142 data1_node *node_values,
1143 data1_attset *attset)
1146 data1_attset_child *c;
1151 for (c = attset->children; c; c = c->next)
1152 writeAttributeValues (zei, node_values, c->child);
1153 for (atts = attset->atts; atts; atts = atts->next)
1155 data1_node *node_value;
1157 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1158 0 /* attr */, node_values);
1159 data1_mk_tag_data_text (zei->dh, node_value, "name",
1160 atts->name, zei->nmem);
1161 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1162 0 /* attr */, node_value);
1163 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1164 atts->value, zei->nmem);
1169 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1176 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1177 data1_node *node_values;
1178 struct oident *entp;
1179 struct data1_attset *attset = NULL;
1181 if ((entp = oid_getentbyoid (o->oid)))
1182 attset = data1_attset_search_id (zei->dh, entp->value);
1185 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1186 attset ? attset->name : "<unknown>");
1189 drec = createRecord (zei->records, &o->sysno);
1191 data1_read_sgml (zei->dh, zei->nmem,
1192 "<explain><attributeSetInfo>AttributeSetInfo\n"
1195 node_attinfo = data1_search_tag (zei->dh, node_root,
1196 "/attributeSetInfo");
1198 assert (node_attinfo);
1199 zebraExplain_initCommonInfo (zei, node_attinfo);
1200 zebraExplain_updateCommonInfo (zei, node_attinfo);
1202 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1203 "oid", o->oid, zei->nmem);
1204 if (attset && attset->name)
1205 data1_mk_tag_data_text (zei->dh, node_attinfo,
1206 "name", attset->name, zei->nmem);
1208 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1209 "attributes", node_attinfo);
1210 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1211 "attributeType", node_attributes);
1212 data1_mk_tag_data_text (zei->dh, node_atttype,
1213 "name", "Use", zei->nmem);
1214 data1_mk_tag_data_text (zei->dh, node_atttype,
1215 "description", "Use Attribute", zei->nmem);
1216 data1_mk_tag_data_int (zei->dh, node_atttype,
1217 "type", 1, zei->nmem);
1218 node_values = data1_mk_tag (zei->dh, zei->nmem,
1219 "attributeValues", 0 /* attr */, node_atttype);
1221 writeAttributeValues (zei, node_values, attset);
1223 /* extract *searchable* keys from it. We do this here, because
1224 record count, etc. is affected */
1226 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1227 /* convert to "SGML" and write it */
1229 data1_pr_tree (zei->dh, node_root, stderr);
1231 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1232 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1233 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1234 drec->size[recInfo_storeData] = sgml_len;
1236 rec_put (zei->records, &drec);
1239 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1241 struct zebDatabaseInfoB *zdi;
1242 data1_node *node_tgtinfo, *node_list, *node_zebra;
1251 trec = rec_get (zei->records, 1);
1252 xfree (trec->info[recInfo_storeData]);
1254 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1256 assert (node_tgtinfo);
1258 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1259 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1261 /* convert to "SGML" and write it */
1263 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1265 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1266 "zebraInfo", node_tgtinfo);
1267 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1268 ZEBRAVER, zei->nmem);
1269 node_list = data1_mk_tag (zei->dh, zei->nmem,
1270 "databaseList", 0 /* attr */, node_zebra);
1271 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1273 data1_node *node_db;
1274 node_db = data1_mk_tag (zei->dh, zei->nmem,
1275 "database", 0 /* attr */, node_list);
1276 data1_mk_tag_data_text (zei->dh, node_db, "name",
1277 zdi->databaseName, zei->nmem);
1278 data1_mk_tag_data_int (zei->dh, node_db, "id",
1279 zdi->sysno, zei->nmem);
1280 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1281 zdi->attributeDetails->sysno, zei->nmem);
1283 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1284 zei->ordinalSU, zei->nmem);
1286 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1287 zei->runNumber, zei->nmem);
1290 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1292 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1294 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1295 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1296 trec->size[recInfo_storeData] = sgml_len;
1298 rec_put (zei->records, &trec);
1301 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1303 struct zebSUInfoB *zsui;
1305 assert (zei->curDatabaseInfo);
1306 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1307 zsui; zsui=zsui->next)
1308 if (zsui->info.use == use && zsui->info.set == set)
1309 return zsui->info.ordinal;
1313 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
1314 int (*f)(void *handle, int ord))
1316 struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1319 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1320 for ( ;zsui; zsui = zsui->next)
1321 (*f)(handle, zsui->info.ordinal);
1326 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1327 const char **db, int *set, int *use)
1329 struct zebDatabaseInfoB *zdb;
1330 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1332 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1333 for ( ;zsui; zsui = zsui->next)
1334 if (zsui->info.ordinal == ord)
1336 *db = zdb->databaseName;
1337 *set = zsui->info.set;
1338 *use = zsui->info.use;
1345 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1346 zebAccessObject *op,
1351 for (ao = *op; ao; ao = ao->next)
1352 if (!oid_oidcmp (oid, ao->oid))
1356 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1359 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1366 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1371 oe.proto = PROTO_Z3950;
1372 oe.oclass = CLASS_ATTSET;
1373 oe.value = (enum oid_value) set;
1375 if (oid_ent_to_oid (&oe, oid))
1377 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1378 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1379 accessInfo->attributeSetIds, oid);
1383 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1385 struct zebSUInfoB *zsui;
1387 assert (zei->curDatabaseInfo);
1388 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1389 zsui; zsui=zsui->next)
1390 if (zsui->info.use == use && zsui->info.set == set)
1392 zebraExplain_addAttributeSet (zei, set);
1393 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1394 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1395 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1396 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1398 zsui->info.set = set;
1399 zsui->info.use = use;
1400 zsui->info.ordinal = (zei->ordinalSU)++;
1401 return zsui->info.ordinal;
1404 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1406 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1407 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1408 accessInfo->schemas, oid);
1411 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1413 assert (zei->curDatabaseInfo);
1417 zei->curDatabaseInfo->recordBytes += adjust_num;
1418 zei->curDatabaseInfo->dirty = 1;
1422 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1424 assert (zei->curDatabaseInfo);
1428 zei->curDatabaseInfo->recordCount += adjust_num;
1429 zei->curDatabaseInfo->dirty = 1;
1433 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1439 return zei->runNumber += adjust_num;
1442 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1444 RecordAttr *recordAttr;
1446 if (rec->info[recInfo_attr])
1447 return (RecordAttr *) rec->info[recInfo_attr];
1448 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1449 rec->info[recInfo_attr] = (char *) recordAttr;
1450 rec->size[recInfo_attr] = sizeof(*recordAttr);
1452 recordAttr->recordSize = 0;
1453 recordAttr->recordOffset = 0;
1454 recordAttr->runNumber = zei->runNumber;
1458 static void att_loadset(void *p, const char *n, const char *name)
1460 data1_handle dh = (data1_handle) p;
1461 if (!data1_get_attset (dh, name))
1462 logf (LOG_WARN, "Directive attset failed for %s", name);
1465 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1467 res_trav(res, "attset", dh, att_loadset);
1471 zebraExplain_addSU adds to AttributeDetails for a database and
1472 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1473 exist for the database.
1475 If the database doesn't exist globally (in TargetInfo) an
1476 AttributeSetInfo must be added (globally).