1 /* $Id: zinfo.c,v 1.36 2003-01-15 07:26:40 oleg Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
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
42 struct zebSUInfo info;
43 struct zebSUInfoB *next;
46 typedef struct zebAccessObjectB *zebAccessObject;
47 struct zebAccessObjectB {
54 typedef struct zebAccessInfoB *zebAccessInfo;
55 struct zebAccessInfoB {
56 zebAccessObject attributeSetIds;
57 zebAccessObject schemas;
61 struct zebSUInfoB *SUInfo;
65 data1_node *data1_tree;
66 } *zebAttributeDetails;
68 struct zebDatabaseInfoB {
69 zebAttributeDetails attributeDetails;
71 data1_node *data1_database;
72 int recordCount; /* records in db */
73 int recordBytes; /* size of records */
74 int sysno; /* sysno of database info */
75 int readFlag; /* 1: read is needed when referenced; 0 if not */
76 int dirty; /* 1: database is dirty: write is needed */
77 struct zebDatabaseInfoB *next;
78 zebAccessInfo accessInfo;
81 struct zebraExplainAttset {
84 struct zebraExplainAttset *next;
87 struct zebraCategoryListInfo {
90 data1_node *data1_categoryList;
93 struct zebraExplainInfo {
101 struct zebraExplainAttset *attsets;
103 data1_node *data1_target;
104 struct zebraCategoryListInfo *categoryList;
105 struct zebDatabaseInfoB *databaseInfo;
106 struct zebDatabaseInfoB *curDatabaseInfo;
107 zebAccessInfo accessInfo;
108 char date[15]; /* YYYY MMDD HH MM SS */
109 int (*updateFunc)(void *handle, Record drec, data1_node *n);
113 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
114 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
116 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
118 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
121 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
122 struct zebDatabaseInfoB *zdi,
124 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
125 zebAttributeDetails zad,
126 const char *databaseName,
128 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
129 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
132 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
133 struct zebraCategoryListInfo *zcl,
137 static Record createRecord (Records records, int *sysno)
142 rec = rec_get (records, *sysno);
143 xfree (rec->info[recInfo_storeData]);
147 rec = rec_new (records);
150 rec->info[recInfo_fileType] =
151 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
152 rec->info[recInfo_databaseName] =
153 rec_strdup ("IR-Explain-1",
154 &rec->size[recInfo_databaseName]);
159 void zebraExplain_flush (ZebraExplainInfo zei, void *handle)
163 zei->updateHandle = handle;
166 struct zebDatabaseInfoB *zdi;
169 /* write each database info record */
170 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
172 zebraExplain_writeDatabase (zei, zdi, 1);
173 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
174 zdi->databaseName, 1);
176 zebraExplain_writeTarget (zei, 1);
177 zebraExplain_writeCategoryList (zei,
180 assert (zei->accessInfo);
181 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
183 zebraExplain_writeAttributeSet (zei, o, 1);
184 for (o = zei->accessInfo->schemas; o; o = o->next)
187 /* zebraExplain_writeSchema (zei, o, 1); */
190 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
192 zebraExplain_writeDatabase (zei, zdi, 0);
193 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
194 zdi->databaseName, 0);
196 zebraExplain_writeTarget (zei, 0);
200 void zebraExplain_close (ZebraExplainInfo zei)
203 yaz_log (LOG_LOG, "zebraExplain_close");
207 zebraExplain_flush (zei, zei->updateHandle);
208 nmem_destroy (zei->nmem);
211 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
216 for (np = n->child; np; np = np->next)
223 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
225 len = np->child->u.data.len;
228 memcpy (str, np->child->u.data.data, len);
231 oid = odr_getoidbystr_nmem (zei->nmem, str);
233 for (ao = *op; ao; ao = ao->next)
234 if (!oid_oidcmp (oid, ao->oid))
241 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
251 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
252 zebAccessInfo *accessInfo)
258 *accessInfo = (zebAccessInfo)
259 nmem_malloc (zei->nmem, sizeof(**accessInfo));
260 (*accessInfo)->attributeSetIds = NULL;
261 (*accessInfo)->schemas = NULL;
265 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
267 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
268 zebraExplain_mergeOids (zei, np,
269 &(*accessInfo)->attributeSetIds);
270 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
271 zebraExplain_mergeOids (zei, np,
272 &(*accessInfo)->schemas);
276 ZebraExplainInfo zebraExplain_open (
277 Records records, data1_handle dh,
281 int (*updateFunc)(void *handle, Record drec, data1_node *n))
284 ZebraExplainInfo zei;
285 struct zebDatabaseInfoB **zdip;
288 NMEM nmem = nmem_create ();
291 logf (LOG_LOG, "zebraExplain_open wr=%d", writeFlag);
293 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
294 zei->write_flag = writeFlag;
295 zei->updateHandle = updateHandle;
296 zei->updateFunc = updateFunc;
298 zei->curDatabaseInfo = NULL;
299 zei->records = records;
304 zei->categoryList = (struct zebraCategoryListInfo *)
305 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
306 zei->categoryList->sysno = 0;
307 zei->categoryList->dirty = 0;
308 zei->categoryList->data1_categoryList = NULL;
310 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
313 tm = localtime (&our_time);
314 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
315 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
316 tm->tm_hour, tm->tm_min, tm->tm_sec);
318 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
321 zdip = &zei->databaseInfo;
322 trec = rec_get (records, 1); /* get "root" record */
327 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
328 if (trec) /* targetInfo already exists ... */
330 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
332 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
334 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
336 if (!zei->data1_target)
339 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
340 nmem_destroy (zei->nmem);
344 data1_pr_tree (zei->dh, zei->data1_target, stderr);
346 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
348 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
351 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
356 node_list = data1_search_tag (zei->dh, node_zebra->child,
359 np = node_list->child;
361 for (; np; np = np->next)
363 data1_node *node_name = NULL;
364 data1_node *node_id = NULL;
365 data1_node *node_aid = NULL;
367 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
369 for (np2 = np->child; np2; np2 = np2->next)
371 if (np2->which != DATA1N_tag)
373 if (!strcmp (np2->u.tag.tag, "name"))
374 node_name = np2->child;
375 else if (!strcmp (np2->u.tag.tag, "id"))
376 node_id = np2->child;
377 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
378 node_aid = np2->child;
380 assert (node_id && node_name && node_aid);
382 *zdip = (struct zebDatabaseInfoB *)
383 nmem_malloc (zei->nmem, sizeof(**zdip));
384 (*zdip)->readFlag = 1;
386 (*zdip)->data1_database = NULL;
387 (*zdip)->recordCount = 0;
388 (*zdip)->recordBytes = 0;
389 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
391 (*zdip)->databaseName = (char *)
392 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
393 memcpy ((*zdip)->databaseName, node_name->u.data.data,
394 node_name->u.data.len);
395 (*zdip)->databaseName[node_name->u.data.len] = '\0';
396 (*zdip)->sysno = atoi_n (node_id->u.data.data,
397 node_id->u.data.len);
398 (*zdip)->attributeDetails = (zebAttributeDetails)
399 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
400 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
401 node_aid->u.data.len);
402 (*zdip)->attributeDetails->readFlag = 1;
403 (*zdip)->attributeDetails->dirty = 0;
404 (*zdip)->attributeDetails->SUInfo = NULL;
406 zdip = &(*zdip)->next;
410 np = data1_search_tag (zei->dh, node_zebra->child,
413 assert (np && np->which == DATA1N_data);
414 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
416 np = data1_search_tag (zei->dh, node_zebra->child,
419 assert (np && np->which == DATA1N_data);
420 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
421 yaz_log (LOG_DEBUG, "read runnumber = %d", zei->runNumber);
426 else /* create initial targetInfo */
428 data1_node *node_tgtinfo;
437 data1_read_sgml (zei->dh, zei->nmem,
438 "<explain><targetInfo>TargetInfo\n"
440 "<namedResultSets>1</>\n"
441 "<multipleDBSearch>1</>\n"
442 "<nicknames><name>Zebra</></>\n"
444 if (!zei->data1_target)
446 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
447 nmem_destroy (zei->nmem);
450 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
452 assert (node_tgtinfo);
454 zebraExplain_initCommonInfo (zei, node_tgtinfo);
455 zebraExplain_initAccessInfo (zei, node_tgtinfo);
457 /* write now because we want to be sure about the sysno */
458 trec = rec_new (records);
459 trec->info[recInfo_fileType] =
460 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
461 trec->info[recInfo_databaseName] =
462 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
464 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
465 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
466 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
467 trec->size[recInfo_storeData] = sgml_len;
469 rec_put (records, &trec);
473 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
475 if (!zei->categoryList->dirty)
477 struct zebraCategoryListInfo *zcl = zei->categoryList;
481 zcl->data1_categoryList =
482 data1_read_sgml (zei->dh, zei->nmem,
483 "<explain><categoryList>CategoryList\n"
486 if (zcl->data1_categoryList)
488 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
491 zebraExplain_initCommonInfo (zei, node_cl);
498 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
499 zebAttributeDetails zad)
502 struct zebSUInfoB **zsuip = &zad->SUInfo;
503 data1_node *node_adinfo, *node_zebra, *node_list, *np;
506 rec = rec_get (zei->records, zad->sysno);
508 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
510 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
511 "/attributeDetails");
512 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
514 node_list = data1_search_tag (zei->dh, node_zebra->child,
516 for (np = node_list->child; np; np = np->next)
518 data1_node *node_set = NULL;
519 data1_node *node_use = NULL;
520 data1_node *node_ordinal = NULL;
525 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
527 for (np2 = np->child; np2; np2 = np2->next)
529 if (np2->which != DATA1N_tag || !np2->child ||
530 np2->child->which != DATA1N_data)
532 if (!strcmp (np2->u.tag.tag, "set"))
533 node_set = np2->child;
534 else if (!strcmp (np2->u.tag.tag, "use"))
535 node_use = np2->child;
536 else if (!strcmp (np2->u.tag.tag, "ordinal"))
537 node_ordinal = np2->child;
539 assert (node_set && node_use && node_ordinal);
541 oid_str_len = node_set->u.data.len;
542 if (oid_str_len >= (int) sizeof(oid_str))
543 oid_str_len = sizeof(oid_str)-1;
544 memcpy (oid_str, node_set->u.data.data, oid_str_len);
545 oid_str[oid_str_len] = '\0';
547 *zsuip = (struct zebSUInfoB *)
548 nmem_malloc (zei->nmem, sizeof(**zsuip));
549 (*zsuip)->info.set = oid_getvalbyname (oid_str);
551 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
552 node_use->u.data.len);
553 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
554 node_ordinal->u.data.len);
555 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
556 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
557 zsuip = &(*zsuip)->next;
564 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
565 struct zebDatabaseInfoB *zdi)
568 data1_node *node_dbinfo, *node_zebra, *np;
571 rec = rec_get (zei->records, zdi->sysno);
573 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
575 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
577 assert (node_dbinfo);
578 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
580 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
583 && (np = data1_search_tag (zei->dh, node_zebra->child,
585 && np->child && np->child->which == DATA1N_data)
586 zdi->recordBytes = atoi_n (np->child->u.data.data,
587 np->child->u.data.len);
588 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
590 (np = data1_search_tag (zei->dh, np->child,
591 "recordCountActual")) &&
592 np->child->which == DATA1N_data)
594 zdi->recordCount = atoi_n (np->child->u.data.data,
595 np->child->u.data.len);
601 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
603 struct zebDatabaseInfoB *zdi;
604 const char *database_n = strrchr (database, '/');
609 database_n = database;
612 if (zei->curDatabaseInfo &&
613 !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
615 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
617 if (!STRCASECMP (zdi->databaseName, database_n))
623 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
628 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
630 zebraExplain_readDatabase (zei, zdi);
632 if (zdi->attributeDetails->readFlag)
635 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
637 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
639 zei->curDatabaseInfo = zdi;
643 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
645 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
646 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
647 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
648 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
651 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
653 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
655 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
659 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
661 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
662 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
663 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
666 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
667 zebAccessInfo accessInfo)
669 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
675 data1_pr_tree (zei->dh, n, stdout);
680 if ((p = accessInfo->attributeSetIds))
682 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
683 for (; p; p = p->next)
684 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
686 if ((p = accessInfo->schemas))
688 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
689 for (; p; p = p->next)
690 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
694 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
695 int explain_database)
697 struct zebDatabaseInfoB *zdi;
698 data1_node *node_dbinfo, *node_adinfo;
699 const char *database_n = strrchr (database, '/');
704 database_n = database;
707 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
710 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
712 if (!STRCASECMP (zdi->databaseName, database_n))
717 /* it's new really. make it */
718 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
719 zdi->next = zei->databaseInfo;
720 zei->databaseInfo = zdi;
722 zdi->recordCount = 0;
723 zdi->recordBytes = 0;
725 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
727 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
732 zdi->data1_database =
733 data1_read_sgml (zei->dh, zei->nmem,
734 "<explain><databaseInfo>DatabaseInfo\n"
736 if (!zdi->data1_database)
739 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
741 assert (node_dbinfo);
743 zebraExplain_initCommonInfo (zei, node_dbinfo);
744 zebraExplain_initAccessInfo (zei, node_dbinfo);
746 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
747 database, zei->nmem);
749 if (explain_database)
750 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
753 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
756 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
760 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
764 zei->curDatabaseInfo = zdi;
766 zdi->attributeDetails = (zebAttributeDetails)
767 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
768 zdi->attributeDetails->readFlag = 0;
769 zdi->attributeDetails->sysno = 0;
770 zdi->attributeDetails->dirty = 1;
771 zdi->attributeDetails->SUInfo = NULL;
772 zdi->attributeDetails->data1_tree =
773 data1_read_sgml (zei->dh, zei->nmem,
774 "<explain><attributeDetails>AttributeDetails\n"
777 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
778 "/attributeDetails");
779 assert (node_adinfo);
781 zebraExplain_initCommonInfo (zei, node_adinfo);
786 static void writeAttributeValueDetails (ZebraExplainInfo zei,
787 zebAttributeDetails zad,
788 data1_node *node_atvs, data1_attset *attset)
791 struct zebSUInfoB *zsui;
792 int set_ordinal = attset->reference;
793 data1_attset_child *c;
795 for (c = attset->children; c; c = c->next)
796 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
797 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
799 data1_node *node_attvalue, *node_value;
800 if (set_ordinal != zsui->info.set)
802 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
803 0 /* attr */, node_atvs);
804 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
805 0 /* attr */, node_attvalue);
806 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
807 zsui->info.use, zei->nmem);
811 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
812 struct zebraCategoryListInfo *zcl,
819 data1_node *node_ci, *node_categoryList;
821 static char *category[] = {
833 node_categoryList = zcl->data1_categoryList;
836 logf (LOG_LOG, "zebraExplain_writeCategoryList");
839 drec = createRecord (zei->records, &sysno);
841 node_ci = data1_search_tag (zei->dh, node_categoryList,
844 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
848 for (i = 0; category[i]; i++)
850 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
851 0 /* attr */, node_ci);
853 data1_mk_tag_data_text (zei->dh, node_cat, "name",
854 category[i], zei->nmem);
856 /* extract *searchable* keys from it. We do this here, because
857 record count, etc. is affected */
859 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
861 /* convert to "SGML" and write it */
863 data1_pr_tree (zei->dh, node_categoryList, stderr);
865 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
866 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
867 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
868 drec->size[recInfo_storeData] = sgml_len;
870 rec_put (zei->records, &drec);
873 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
874 zebAttributeDetails zad,
875 const char *databaseName,
881 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
882 struct zebSUInfoB *zsui;
890 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
893 drec = createRecord (zei->records, &zad->sysno);
894 assert (zad->data1_tree);
896 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
897 "/attributeDetails");
898 zebraExplain_updateCommonInfo (zei, node_adinfo);
900 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
901 databaseName, zei->nmem);
903 /* extract *searchable* keys from it. We do this here, because
904 record count, etc. is affected */
906 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
908 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
909 "attributesBySet", node_adinfo);
913 data1_node *node_asd;
914 data1_attset *attset;
915 int set_ordinal = -1;
916 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
918 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
919 && zsui->info.set > set_min)
920 set_ordinal = zsui->info.set;
924 set_min = set_ordinal;
925 node_asd = data1_mk_tag (zei->dh, zei->nmem,
926 "attributeSetDetails",
927 0 /* attr */, node_attributesBySet);
929 attset = data1_attset_search_id (zei->dh, set_ordinal);
932 zebraExplain_loadAttsets (zei->dh, zei->res);
933 attset = data1_attset_search_id (zei->dh, set_ordinal);
940 oe.proto = PROTO_Z3950;
941 oe.oclass = CLASS_ATTSET;
942 oe.value = (enum oid_value) set_ordinal;
944 if (oid_ent_to_oid (&oe, oid))
946 data1_node *node_abt, *node_atd, *node_atvs;
947 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
950 node_abt = data1_mk_tag (zei->dh, zei->nmem,
952 0 /*attr */, node_asd);
953 node_atd = data1_mk_tag (zei->dh, zei->nmem,
954 "attributeTypeDetails",
955 0 /* attr */, node_abt);
956 data1_mk_tag_data_int (zei->dh, node_atd,
957 "type", 1, zei->nmem);
958 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
960 0 /* attr */, node_atd);
961 writeAttributeValueDetails (zei, zad, node_atvs, attset);
965 /* zebra info (private) */
966 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
967 "zebraInfo", node_adinfo);
968 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
969 "attrlist", node_zebra);
970 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
972 struct oident oident;
974 data1_node *node_attr;
976 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
979 oident.proto = PROTO_Z3950;
980 oident.oclass = CLASS_ATTSET;
981 oident.value = (enum oid_value) zsui->info.set;
982 oid_ent_to_oid (&oident, oid);
984 data1_mk_tag_data_text (zei->dh, node_attr, "set",
985 oident.desc, zei->nmem);
986 data1_mk_tag_data_int (zei->dh, node_attr, "use",
987 zsui->info.use, zei->nmem);
988 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
989 zsui->info.ordinal, zei->nmem);
991 /* convert to "SGML" and write it */
993 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
995 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
997 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
998 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
999 drec->size[recInfo_storeData] = sgml_len;
1001 rec_put (zei->records, &drec);
1004 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
1005 struct zebDatabaseInfoB *zdi,
1011 data1_node *node_dbinfo, *node_count, *node_zebra;
1018 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1020 drec = createRecord (zei->records, &zdi->sysno);
1021 assert (zdi->data1_database);
1023 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1026 assert (node_dbinfo);
1027 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1028 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1030 /* extract *searchable* keys from it. We do this here, because
1031 record count, etc. is affected */
1033 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1035 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1036 "recordCount", node_dbinfo);
1037 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1038 zdi->recordCount, zei->nmem);
1040 /* zebra info (private) */
1041 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1042 "zebraInfo", node_dbinfo);
1043 data1_mk_tag_data_int (zei->dh, node_zebra,
1044 "recordBytes", zdi->recordBytes, zei->nmem);
1045 /* convert to "SGML" and write it */
1047 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1049 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1051 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1052 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1053 drec->size[recInfo_storeData] = sgml_len;
1055 rec_put (zei->records, &drec);
1058 static void writeAttributeValues (ZebraExplainInfo zei,
1059 data1_node *node_values,
1060 data1_attset *attset)
1063 data1_attset_child *c;
1068 for (c = attset->children; c; c = c->next)
1069 writeAttributeValues (zei, node_values, c->child);
1070 for (atts = attset->atts; atts; atts = atts->next)
1072 data1_node *node_value;
1074 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1075 0 /* attr */, node_values);
1076 data1_mk_tag_data_text (zei->dh, node_value, "name",
1077 atts->name, zei->nmem);
1078 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1079 0 /* attr */, node_value);
1080 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1081 atts->value, zei->nmem);
1086 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1093 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1094 data1_node *node_values;
1095 struct oident *entp;
1096 struct data1_attset *attset = NULL;
1098 if ((entp = oid_getentbyoid (o->oid)))
1099 attset = data1_attset_search_id (zei->dh, entp->value);
1102 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1103 attset ? attset->name : "<unknown>");
1106 drec = createRecord (zei->records, &o->sysno);
1108 data1_read_sgml (zei->dh, zei->nmem,
1109 "<explain><attributeSetInfo>AttributeSetInfo\n"
1112 node_attinfo = data1_search_tag (zei->dh, node_root,
1113 "/attributeSetInfo");
1115 assert (node_attinfo);
1116 zebraExplain_initCommonInfo (zei, node_attinfo);
1117 zebraExplain_updateCommonInfo (zei, node_attinfo);
1119 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1120 "oid", o->oid, zei->nmem);
1121 if (attset && attset->name)
1122 data1_mk_tag_data_text (zei->dh, node_attinfo,
1123 "name", attset->name, zei->nmem);
1125 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1126 "attributes", node_attinfo);
1127 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1128 "attributeType", node_attributes);
1129 data1_mk_tag_data_text (zei->dh, node_atttype,
1130 "name", "Use", zei->nmem);
1131 data1_mk_tag_data_text (zei->dh, node_atttype,
1132 "description", "Use Attribute", zei->nmem);
1133 data1_mk_tag_data_int (zei->dh, node_atttype,
1134 "type", 1, zei->nmem);
1135 node_values = data1_mk_tag (zei->dh, zei->nmem,
1136 "attributeValues", 0 /* attr */, node_atttype);
1138 writeAttributeValues (zei, node_values, attset);
1140 /* extract *searchable* keys from it. We do this here, because
1141 record count, etc. is affected */
1143 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1144 /* convert to "SGML" and write it */
1146 data1_pr_tree (zei->dh, node_root, stderr);
1148 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1149 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1150 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1151 drec->size[recInfo_storeData] = sgml_len;
1153 rec_put (zei->records, &drec);
1156 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1158 struct zebDatabaseInfoB *zdi;
1159 data1_node *node_tgtinfo, *node_list, *node_zebra;
1168 trec = rec_get (zei->records, 1);
1169 xfree (trec->info[recInfo_storeData]);
1171 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1173 assert (node_tgtinfo);
1175 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1176 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1178 /* convert to "SGML" and write it */
1180 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1182 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1183 "zebraInfo", node_tgtinfo);
1184 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1185 ZEBRAVER, zei->nmem);
1186 node_list = data1_mk_tag (zei->dh, zei->nmem,
1187 "databaseList", 0 /* attr */, node_zebra);
1188 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1190 data1_node *node_db;
1191 node_db = data1_mk_tag (zei->dh, zei->nmem,
1192 "database", 0 /* attr */, node_list);
1193 data1_mk_tag_data_text (zei->dh, node_db, "name",
1194 zdi->databaseName, zei->nmem);
1195 data1_mk_tag_data_int (zei->dh, node_db, "id",
1196 zdi->sysno, zei->nmem);
1197 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1198 zdi->attributeDetails->sysno, zei->nmem);
1200 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1201 zei->ordinalSU, zei->nmem);
1203 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1204 zei->runNumber, zei->nmem);
1207 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1209 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1211 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1212 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1213 trec->size[recInfo_storeData] = sgml_len;
1215 rec_put (zei->records, &trec);
1218 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1220 struct zebSUInfoB *zsui;
1222 assert (zei->curDatabaseInfo);
1223 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1224 zsui; zsui=zsui->next)
1225 if (zsui->info.use == use && zsui->info.set == set)
1226 return zsui->info.ordinal;
1230 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1231 const char **db, int *set, int *use)
1233 struct zebDatabaseInfoB *zdb;
1234 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1236 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1237 for ( ;zsui; zsui = zsui->next)
1238 if (zsui->info.ordinal == ord)
1240 *db = zdb->databaseName;
1241 *set = zsui->info.set;
1242 *use = zsui->info.use;
1249 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1250 zebAccessObject *op,
1255 for (ao = *op; ao; ao = ao->next)
1256 if (!oid_oidcmp (oid, ao->oid))
1260 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1263 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1270 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1275 oe.proto = PROTO_Z3950;
1276 oe.oclass = CLASS_ATTSET;
1277 oe.value = (enum oid_value) set;
1279 if (oid_ent_to_oid (&oe, oid))
1281 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1282 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1283 accessInfo->attributeSetIds, oid);
1287 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1289 struct zebSUInfoB *zsui;
1291 assert (zei->curDatabaseInfo);
1292 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1293 zsui; zsui=zsui->next)
1294 if (zsui->info.use == use && zsui->info.set == set)
1296 zebraExplain_addAttributeSet (zei, set);
1297 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1298 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1299 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1300 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1302 zsui->info.set = set;
1303 zsui->info.use = use;
1304 zsui->info.ordinal = (zei->ordinalSU)++;
1305 return zsui->info.ordinal;
1308 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1310 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1311 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1312 accessInfo->schemas, oid);
1315 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1317 assert (zei->curDatabaseInfo);
1321 zei->curDatabaseInfo->recordBytes += adjust_num;
1322 zei->curDatabaseInfo->dirty = 1;
1326 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1328 assert (zei->curDatabaseInfo);
1332 zei->curDatabaseInfo->recordCount += adjust_num;
1333 zei->curDatabaseInfo->dirty = 1;
1337 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1343 return zei->runNumber += adjust_num;
1346 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1348 RecordAttr *recordAttr;
1350 if (rec->info[recInfo_attr])
1351 return (RecordAttr *) rec->info[recInfo_attr];
1352 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1353 rec->info[recInfo_attr] = (char *) recordAttr;
1354 rec->size[recInfo_attr] = sizeof(*recordAttr);
1356 recordAttr->recordSize = 0;
1357 recordAttr->recordOffset = 0;
1358 recordAttr->runNumber = zei->runNumber;
1362 static void att_loadset(void *p, const char *n, const char *name)
1364 data1_handle dh = (data1_handle) p;
1365 if (!data1_get_attset (dh, name))
1366 logf (LOG_WARN, "Directive attset failed for %s", name);
1369 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1371 res_trav(res, "attset", dh, att_loadset);
1375 zebraExplain_addSU adds to AttributeDetails for a database and
1376 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1377 exist for the database.
1379 If the database doesn't exist globally (in TargetInfo) an
1380 AttributeSetInfo must be added (globally).