2 * Copyright (C) 1994-1998, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.8 1998-05-20 10:12:20 adam
8 * Implemented automatic EXPLAIN database maintenance.
9 * Modified Zebra to work with ASN.1 compiled version of YAZ.
11 * Revision 1.7 1998/03/05 08:45:13 adam
12 * New result set model and modular ranking system. Moved towards
13 * descent server API. System information stored as "SGML" records.
15 * Revision 1.6 1998/02/17 10:29:27 adam
16 * Moved towards 'automatic' EXPLAIN database.
18 * Revision 1.5 1997/10/27 14:33:05 adam
19 * Moved towards generic character mapping depending on "structure"
20 * field in abstract syntax file. Fixed a few memory leaks. Fixed
21 * bug with negative integers when doing searches with relational
24 * Revision 1.4 1997/09/25 14:57:08 adam
27 * Revision 1.3 1996/05/22 08:21:59 adam
28 * Added public ZebDatabaseInfo structure.
30 * Revision 1.2 1996/05/14 06:16:41 adam
31 * Compact use/set bytes used in search service.
33 * Revision 1.1 1996/05/13 14:23:07 adam
34 * Work on compaction of set/use bytes in dictionary.
55 struct zebSUInfo info;
56 struct zebSUInfoB *next;
59 typedef struct zebAccessObjectB *zebAccessObject;
60 struct zebAccessObjectB {
67 typedef struct zebAccessInfoB *zebAccessInfo;
68 struct zebAccessInfoB {
69 zebAccessObject attributeSetIds;
70 zebAccessObject schemas;
74 struct zebSUInfoB *SUInfo;
78 data1_node *data1_tree;
79 } *zebAttributeDetails;
81 struct zebDatabaseInfoB {
82 zebAttributeDetails attributeDetails;
84 data1_node *data1_database;
85 int recordCount; /* records in db */
86 int recordBytes; /* size of records */
87 int sysno; /* sysno of database info */
88 int readFlag; /* 1: read is needed when referenced; 0 if not */
89 int dirty; /* 1: database is dirty: write is needed */
90 struct zebDatabaseInfoB *next;
91 zebAccessInfo accessInfo;
94 struct zebraExplainAttset {
97 struct zebraExplainAttset *next;
100 struct zebraExplainInfo {
107 struct zebraExplainAttset *attsets;
109 data1_node *data1_target;
110 struct zebDatabaseInfoB *databaseInfo;
111 struct zebDatabaseInfoB *curDatabaseInfo;
112 zebAccessInfo accessInfo;
113 char date[15]; /* YYYY MMDD HH MM SS */
114 int (*updateFunc)(void *handle, Record drec, data1_node *n);
118 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
119 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
121 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
123 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
126 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
129 logf (LOG_DEBUG, "data1_search_tag %s", tag);
130 for (; n; n = n->next)
131 if (n->which == DATA1N_tag && n->u.tag.tag &&
132 !yaz_matchstr (tag, n->u.tag.tag))
134 logf (LOG_DEBUG, " found");
137 logf (LOG_DEBUG, " not found");
141 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
142 const char *tag, NMEM nmem)
144 data1_node *partag = get_parent_tag(dh, at);
145 data1_node *res = data1_mk_node (dh, nmem);
146 data1_element *e = NULL;
149 res->which = DATA1N_tag;
150 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
151 res->u.tag.node_selected = 0;
152 res->u.tag.make_variantlist = 0;
153 res->u.tag.no_data_requested = 0;
154 res->u.tag.get_bytes = -1;
157 e = partag->u.tag.element;
159 data1_getelementbytagname (dh, at->root->u.root.absyn,
161 res->root = at->root;
166 assert (at->last_child);
167 at->last_child->next = res;
169 at->last_child = res;
173 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
174 const char *tag, NMEM nmem)
176 data1_node *node = data1_search_tag (dh, at->child, tag);
178 node = data1_add_tag (dh, at, tag, nmem);
180 node->child = node->last_child = NULL;
184 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
185 const char *tag, int num,
188 data1_node *node_data;
190 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
193 node_data->u.data.what = DATA1I_num;
194 node_data->u.data.data = node_data->lbuf;
195 sprintf (node_data->u.data.data, "%d", num);
196 node_data->u.data.len = strlen (node_data->u.data.data);
200 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
201 const char *tag, Odr_oid *oid,
204 data1_node *node_data;
205 char str[128], *p = str;
208 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
212 for (ii = oid; *ii >= 0; ii++)
216 sprintf (p, "%d", *ii);
219 node_data->u.data.what = DATA1I_oid;
220 node_data->u.data.len = strlen (str);
221 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
226 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
227 const char *tag, const char *str,
230 data1_node *node_data;
232 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
235 node_data->u.data.what = DATA1I_text;
236 node_data->u.data.len = strlen (str);
237 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
241 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
242 const char *tag, const char *str,
245 data1_node *node = data1_search_tag (dh, at->child, tag);
247 return data1_add_tagdata_text (dh, at, tag, str, nmem);
250 data1_node *node_data = node->child;
251 node_data->u.data.what = DATA1I_text;
252 node_data->u.data.data = node_data->lbuf;
253 strcpy (node_data->u.data.data, str);
254 node_data->u.data.len = strlen (node_data->u.data.data);
259 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
260 struct zebDatabaseInfoB *zdi,
262 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
263 zebAttributeDetails zad,
264 const char *databaseName,
266 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
267 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
271 static Record createRecord (Records records, int *sysno)
276 rec = rec_get (records, *sysno);
277 xfree (rec->info[recInfo_storeData]);
281 rec = rec_new (records);
284 rec->info[recInfo_fileType] =
285 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
286 rec->info[recInfo_databaseName] =
287 rec_strdup ("IR-Explain-1",
288 &rec->size[recInfo_databaseName]);
293 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag,
294 int (*updateH)(Record drec, data1_node *n))
296 struct zebDatabaseInfoB *zdi;
298 logf (LOG_DEBUG, "zebraExplain_close wr=%d", writeFlag);
302 /* write each database info record */
303 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
305 zebraExplain_writeDatabase (zei, zdi, 1);
306 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
307 zdi->databaseName, 1);
309 zebraExplain_writeTarget (zei, 1);
311 assert (zei->accessInfo);
312 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
314 zebraExplain_writeAttributeSet (zei, o, 1);
315 for (o = zei->accessInfo->schemas; o; o = o->next)
318 /* zebraExplain_writeSchema (zei, o, 1); */
321 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
323 zebraExplain_writeDatabase (zei, zdi, 0);
324 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
325 zdi->databaseName, 0);
327 zebraExplain_writeTarget (zei, 0);
330 nmem_destroy (zei->nmem);
334 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
339 for (np = n->child; np; np = np->next)
346 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
348 len = np->child->u.data.len;
351 memcpy (str, np->child->u.data.data, len);
354 oid = odr_getoidbystr_nmem (zei->nmem, str);
356 for (ao = *op; ao; ao = ao->next)
357 if (!oid_oidcmp (oid, ao->oid))
364 ao = nmem_malloc (zei->nmem, sizeof(*ao));
374 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
375 zebAccessInfo *accessInfo)
381 *accessInfo = nmem_malloc (zei->nmem, sizeof(**accessInfo));
382 (*accessInfo)->attributeSetIds = NULL;
383 (*accessInfo)->schemas = NULL;
387 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
389 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
390 zebraExplain_mergeOids (zei, np,
391 &(*accessInfo)->attributeSetIds);
392 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
393 zebraExplain_mergeOids (zei, np,
394 &(*accessInfo)->schemas);
398 ZebraExplainInfo zebraExplain_open (
399 Records records, data1_handle dh,
403 int (*updateFunc)(void *handle, Record drec, data1_node *n))
406 ZebraExplainInfo zei;
407 struct zebDatabaseInfoB **zdip;
411 logf (LOG_DEBUG, "zebraExplain_open wr=%d", writeFlag);
412 zei = xmalloc (sizeof(*zei));
413 zei->updateHandle = updateHandle;
414 zei->updateFunc = updateFunc;
416 zei->curDatabaseInfo = NULL;
417 zei->records = records;
418 zei->nmem = nmem_create ();
424 tm = localtime (&our_time);
425 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
426 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
427 tm->tm_hour, tm->tm_min, tm->tm_sec);
429 zdip = &zei->databaseInfo;
430 trec = rec_get (records, 1); /* get "root" record */
432 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
433 if (trec) /* targetInfo already exists ... */
435 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
437 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
440 data1_pr_tree (zei->dh, zei->data1_target, stderr);
442 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
444 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
447 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
449 node_list = data1_search_tag (zei->dh, node_zebra->child,
451 for (np = node_list->child; np; np = np->next)
453 data1_node *node_name = NULL;
454 data1_node *node_id = NULL;
455 data1_node *node_aid = NULL;
457 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
459 for (np2 = np->child; np2; np2 = np2->next)
461 if (np2->which != DATA1N_tag)
463 if (!strcmp (np2->u.tag.tag, "name"))
464 node_name = np2->child;
465 else if (!strcmp (np2->u.tag.tag, "id"))
466 node_id = np2->child;
467 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
468 node_aid = np2->child;
470 assert (node_id && node_name && node_aid);
472 *zdip = nmem_malloc (zei->nmem, sizeof(**zdip));
474 (*zdip)->readFlag = 1;
476 (*zdip)->data1_database = NULL;
477 (*zdip)->recordCount = 0;
478 (*zdip)->recordBytes = 0;
479 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
481 (*zdip)->databaseName = nmem_malloc (zei->nmem,
482 1+node_name->u.data.len);
483 memcpy ((*zdip)->databaseName, node_name->u.data.data,
484 node_name->u.data.len);
485 (*zdip)->databaseName[node_name->u.data.len] = '\0';
486 (*zdip)->sysno = atoi_n (node_id->u.data.data,
487 node_id->u.data.len);
488 (*zdip)->attributeDetails =
489 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
490 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
491 node_aid->u.data.len);
492 (*zdip)->attributeDetails->readFlag = 1;
493 (*zdip)->attributeDetails->dirty = 0;
494 (*zdip)->attributeDetails->SUInfo = NULL;
496 zdip = &(*zdip)->next;
498 np = data1_search_tag (zei->dh, node_zebra->child,
501 assert (np && np->which == DATA1N_data);
502 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
504 np = data1_search_tag (zei->dh, node_zebra->child,
507 assert (np && np->which == DATA1N_data);
508 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
512 else /* create initial targetInfo */
514 data1_node *node_tgtinfo;
524 data1_read_sgml (zei->dh, zei->nmem,
525 "<explain><targetInfo>TargetInfo\n"
527 "<namedResultSets>1</>\n"
528 "<multipleDBSearch>1</>\n"
529 "<nicknames><name>Zebra</></>\n"
532 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
534 assert (node_tgtinfo);
537 zebraExplain_initCommonInfo (zei, node_tgtinfo);
538 zebraExplain_initAccessInfo (zei, node_tgtinfo);
540 /* write now because we want to be sure about the sysno */
541 trec = rec_new (records);
542 trec->info[recInfo_fileType] =
543 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
544 trec->info[recInfo_databaseName] =
545 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
547 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
548 trec->info[recInfo_storeData] = xmalloc (sgml_len);
549 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
550 trec->size[recInfo_storeData] = sgml_len;
552 rec_put (records, &trec);
556 zebraExplain_newDatabase (zei, "IR-Explain-1");
561 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
562 zebAttributeDetails zad)
565 struct zebSUInfoB **zsuip = &zad->SUInfo;
566 data1_node *node_adinfo, *node_zebra, *node_list, *np;
569 rec = rec_get (zei->records, zad->sysno);
571 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
573 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
575 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
577 node_list = data1_search_tag (zei->dh, node_zebra->child,
579 for (np = node_list->child; np; np = np->next)
581 data1_node *node_set = NULL;
582 data1_node *node_use = NULL;
583 data1_node *node_ordinal = NULL;
585 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
587 for (np2 = np->child; np2; np2 = np2->next)
589 if (np2->which != DATA1N_tag || !np2->child ||
590 np2->child->which != DATA1N_data)
592 if (!strcmp (np2->u.tag.tag, "set"))
593 node_set = np2->child;
594 else if (!strcmp (np2->u.tag.tag, "use"))
595 node_use = np2->child;
596 else if (!strcmp (np2->u.tag.tag, "ordinal"))
597 node_ordinal = np2->child;
599 assert (node_set && node_use && node_ordinal);
601 *zsuip = nmem_malloc (zei->nmem, sizeof(**zsuip));
602 (*zsuip)->info.set = atoi_n (node_set->u.data.data,
603 node_set->u.data.len);
604 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
605 node_use->u.data.len);
606 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
607 node_ordinal->u.data.len);
608 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
609 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
610 zsuip = &(*zsuip)->next;
617 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
618 struct zebDatabaseInfoB *zdi)
621 data1_node *node_dbinfo, *node_zebra, *np;
624 rec = rec_get (zei->records, zdi->sysno);
626 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
628 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
630 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
632 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
634 np = data1_search_tag (zei->dh, node_dbinfo->child,
636 if (np && np->child && np->child->which == DATA1N_data)
637 zdi->recordBytes = atoi_n (np->child->u.data.data,
638 np->child->u.data.len);
639 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
641 (np = data1_search_tag (zei->dh, np->child,
642 "recordCountActual")) &&
643 np->child->which == DATA1N_data)
645 zdi->recordCount = atoi_n (np->child->u.data.data,
646 np->child->u.data.len);
652 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
654 struct zebDatabaseInfoB *zdi;
657 if (zei->curDatabaseInfo &&
658 !strcmp (zei->curDatabaseInfo->databaseName, database))
660 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
662 if (!strcmp (zdi->databaseName, database))
668 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
673 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
675 zebraExplain_readDatabase (zei, zdi);
677 if (zdi->attributeDetails->readFlag)
680 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
682 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
684 zei->curDatabaseInfo = zdi;
688 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
690 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
692 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
693 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
694 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
697 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
699 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
701 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
704 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
706 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
707 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
708 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
711 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
712 zebAccessInfo accessInfo)
714 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
720 if ((p = accessInfo->attributeSetIds))
722 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
723 for (; p; p = p->next)
724 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
726 if ((p = accessInfo->schemas))
728 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
729 for (; p; p = p->next)
730 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
734 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database)
736 struct zebDatabaseInfoB *zdi;
737 data1_node *node_dbinfo, *node_adinfo;
740 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
743 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
745 if (!strcmp (zdi->databaseName, database))
750 /* it's new really. make it */
751 zdi = nmem_malloc (zei->nmem, sizeof(*zdi));
752 zdi->next = zei->databaseInfo;
753 zei->databaseInfo = zdi;
755 zdi->recordCount = 0;
756 zdi->recordBytes = 0;
758 zdi->databaseName = nmem_strdup (zei->nmem, database);
760 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
765 zdi->data1_database =
766 data1_read_sgml (zei->dh, zei->nmem,
767 "<explain><databaseInfo>DatabaseInfo\n"
770 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
772 assert (node_dbinfo);
774 zebraExplain_initCommonInfo (zei, node_dbinfo);
775 zebraExplain_initAccessInfo (zei, node_dbinfo);
777 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
778 database, zei->nmem);
780 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
783 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
787 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
791 zei->curDatabaseInfo = zdi;
793 zdi->attributeDetails =
794 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
795 zdi->attributeDetails->readFlag = 0;
796 zdi->attributeDetails->sysno = 0;
797 zdi->attributeDetails->dirty = 1;
798 zdi->attributeDetails->data1_tree =
799 data1_read_sgml (zei->dh, zei->nmem,
800 "<explain><attributeDetails>AttributeDetails\n"
804 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
806 assert (node_adinfo);
808 zebraExplain_initCommonInfo (zei, node_adinfo);
813 static void writeAttributeValueDetails (ZebraExplainInfo zei,
814 zebAttributeDetails zad,
815 data1_node *node_atvs, data1_attset *attset)
818 struct zebSUInfoB *zsui;
819 int set_ordinal = attset->reference;
820 data1_attset_child *c;
822 for (c = attset->children; c; c = c->next)
823 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
824 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
826 data1_node *node_attvalue, *node_value;
827 if (set_ordinal != zsui->info.set)
829 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
831 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
833 data1_add_tagdata_int (zei->dh, node_value, "numeric",
834 zsui->info.use, zei->nmem);
838 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
839 zebAttributeDetails zad,
840 const char *databaseName,
846 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
847 struct zebSUInfoB *zsui;
855 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
858 drec = createRecord (zei->records, &zad->sysno);
859 assert (zad->data1_tree);
860 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
862 zebraExplain_updateCommonInfo (zei, node_adinfo);
864 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
865 databaseName, zei->nmem);
867 /* extract *searchable* keys from it. We do this here, because
868 record count, etc. is affected */
870 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
872 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
873 "attributesBySet", zei->nmem);
877 data1_node *node_asd;
878 data1_attset *attset;
879 int set_ordinal = -1;
880 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
882 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
883 && zsui->info.set > set_min)
884 set_ordinal = zsui->info.set;
888 set_min = set_ordinal;
889 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
890 "attributeSetDetails", zei->nmem);
892 attset = data1_attset_search_id (zei->dh, set_ordinal);
895 zebraExplain_loadAttsets (zei->dh, zei->res);
896 attset = data1_attset_search_id (zei->dh, set_ordinal);
903 oe.proto = PROTO_Z3950;
904 oe.oclass = CLASS_ATTSET;
905 oe.value = set_ordinal;
907 if (oid_ent_to_oid (&oe, oid))
909 data1_node *node_abt, *node_atd, *node_atvs;
910 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
913 node_abt = data1_add_tag (zei->dh, node_asd,
914 "attributesByType", zei->nmem);
915 node_atd = data1_add_tag (zei->dh, node_abt,
916 "attributeTypeDetails", zei->nmem);
917 data1_add_tagdata_int (zei->dh, node_atd,
918 "type", 1, zei->nmem);
919 node_atvs = data1_add_tag (zei->dh, node_atd,
920 "attributeValues", zei->nmem);
921 writeAttributeValueDetails (zei, zad, node_atvs, attset);
925 /* zebra info (private) */
926 node_zebra = data1_make_tag (zei->dh, node_adinfo,
927 "zebraInfo", zei->nmem);
928 node_list = data1_make_tag (zei->dh, node_zebra,
929 "attrlist", zei->nmem);
930 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
932 data1_node *node_attr;
933 node_attr = data1_add_tag (zei->dh, node_list,
935 data1_add_tagdata_int (zei->dh, node_attr, "set",
936 zsui->info.set, zei->nmem);
937 data1_add_tagdata_int (zei->dh, node_attr, "use",
938 zsui->info.use, zei->nmem);
939 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
940 zsui->info.ordinal, zei->nmem);
942 /* convert to "SGML" and write it */
944 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
946 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
948 drec->info[recInfo_storeData] = xmalloc (sgml_len);
949 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
950 drec->size[recInfo_storeData] = sgml_len;
952 rec_put (zei->records, &drec);
955 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
956 struct zebDatabaseInfoB *zdi,
962 data1_node *node_dbinfo, *node_count, *node_zebra;
969 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
971 drec = createRecord (zei->records, &zdi->sysno);
972 assert (zdi->data1_database);
973 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
976 zebraExplain_updateCommonInfo (zei, node_dbinfo);
977 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
979 /* extract *searchable* keys from it. We do this here, because
980 record count, etc. is affected */
982 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
984 node_count = data1_make_tag (zei->dh, node_dbinfo,
985 "recordCount", zei->nmem);
986 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
987 zdi->recordCount, zei->nmem);
989 /* zebra info (private) */
990 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
991 "zebraInfo", zei->nmem);
992 data1_add_tagdata_int (zei->dh, node_zebra,
993 "recordBytes", zdi->recordBytes, zei->nmem);
994 /* convert to "SGML" and write it */
996 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
998 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1000 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1001 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1002 drec->size[recInfo_storeData] = sgml_len;
1004 rec_put (zei->records, &drec);
1007 static void writeAttributeValues (ZebraExplainInfo zei,
1008 data1_node *node_values,
1009 data1_attset *attset)
1012 data1_attset_child *c;
1017 for (c = attset->children; c; c = c->next)
1018 writeAttributeValues (zei, node_values, c->child);
1019 for (atts = attset->atts; atts; atts = atts->next)
1021 data1_node *node_value;
1023 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1025 data1_add_tagdata_text (zei->dh, node_value, "name",
1026 atts->name, zei->nmem);
1027 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1028 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1029 atts->value, zei->nmem);
1034 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1041 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1042 data1_node *node_values;
1043 struct oident *entp;
1044 struct data1_attset *attset = NULL;
1046 if ((entp = oid_getentbyoid (o->oid)))
1047 attset = data1_attset_search_id (zei->dh, entp->value);
1050 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1051 attset ? attset->name : "<unknown>");
1054 drec = createRecord (zei->records, &o->sysno);
1056 data1_read_sgml (zei->dh, zei->nmem,
1057 "<explain><attributeSetInfo>AttributeSetInfo\n"
1060 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1061 "attributeSetInfo");
1063 zebraExplain_initCommonInfo (zei, node_attinfo);
1064 zebraExplain_updateCommonInfo (zei, node_attinfo);
1066 data1_add_tagdata_oid (zei->dh, node_attinfo,
1067 "oid", o->oid, zei->nmem);
1068 if (attset && attset->name)
1069 data1_add_tagdata_text (zei->dh, node_attinfo,
1070 "name", attset->name, zei->nmem);
1072 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1073 "attributes", zei->nmem);
1074 node_atttype = data1_make_tag (zei->dh, node_attributes,
1075 "attributeType", zei->nmem);
1076 data1_add_tagdata_text (zei->dh, node_atttype,
1077 "name", "Use", zei->nmem);
1078 data1_add_tagdata_text (zei->dh, node_atttype,
1079 "description", "Use Attribute", zei->nmem);
1080 data1_add_tagdata_int (zei->dh, node_atttype,
1081 "type", 1, zei->nmem);
1082 node_values = data1_add_tag (zei->dh, node_atttype,
1083 "attributeValues", zei->nmem);
1085 writeAttributeValues (zei, node_values, attset);
1087 /* extract *searchable* keys from it. We do this here, because
1088 record count, etc. is affected */
1090 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1091 /* convert to "SGML" and write it */
1093 data1_pr_tree (zei->dh, node_root, stderr);
1095 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1096 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1097 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1098 drec->size[recInfo_storeData] = sgml_len;
1100 rec_put (zei->records, &drec);
1103 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1105 struct zebDatabaseInfoB *zdi;
1106 data1_node *node_tgtinfo, *node_list, *node_zebra;
1115 trec = rec_get (zei->records, 1);
1116 xfree (trec->info[recInfo_storeData]);
1118 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1120 assert (node_tgtinfo);
1122 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1123 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1125 /* convert to "SGML" and write it */
1127 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1129 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1130 "zebraInfo", zei->nmem);
1131 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1132 ZEBRAVER, zei->nmem);
1133 node_list = data1_add_tag (zei->dh, node_zebra,
1134 "databaseList", zei->nmem);
1135 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1137 data1_node *node_db;
1138 node_db = data1_add_tag (zei->dh, node_list,
1139 "database", zei->nmem);
1140 data1_add_tagdata_text (zei->dh, node_db, "name",
1141 zdi->databaseName, zei->nmem);
1142 data1_add_tagdata_int (zei->dh, node_db, "id",
1143 zdi->sysno, zei->nmem);
1144 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1145 zdi->attributeDetails->sysno, zei->nmem);
1147 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1148 zei->ordinalSU, zei->nmem);
1150 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1151 zei->runNumber, zei->nmem);
1154 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1156 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1158 trec->info[recInfo_storeData] = xmalloc (sgml_len);
1159 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1160 trec->size[recInfo_storeData] = sgml_len;
1162 rec_put (zei->records, &trec);
1165 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1167 struct zebSUInfoB *zsui;
1169 assert (zei->curDatabaseInfo);
1170 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1171 zsui; zsui=zsui->next)
1172 if (zsui->info.use == use && zsui->info.set == set)
1173 return zsui->info.ordinal;
1177 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1178 zebAccessObject *op,
1183 for (ao = *op; ao; ao = ao->next)
1184 if (!oid_oidcmp (oid, ao->oid))
1188 ao = nmem_malloc (zei->nmem, sizeof(*ao));
1191 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1198 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1203 oe.proto = PROTO_Z3950;
1204 oe.oclass = CLASS_ATTSET;
1207 if (oid_ent_to_oid (&oe, oid))
1209 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1210 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1211 accessInfo->attributeSetIds, oid);
1215 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1217 struct zebSUInfoB *zsui;
1219 assert (zei->curDatabaseInfo);
1220 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1221 zsui; zsui=zsui->next)
1222 if (zsui->info.use == use && zsui->info.set == set)
1224 zebraExplain_addAttributeSet (zei, set);
1225 zsui = nmem_malloc (zei->nmem, sizeof(*zsui));
1226 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1227 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1228 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1230 zsui->info.set = set;
1231 zsui->info.use = use;
1232 zsui->info.ordinal = (zei->ordinalSU)++;
1233 return zsui->info.ordinal;
1236 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1238 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1239 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1240 accessInfo->schemas, oid);
1243 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1245 assert (zei->curDatabaseInfo);
1249 zei->curDatabaseInfo->recordBytes += adjust_num;
1250 zei->curDatabaseInfo->dirty = 1;
1254 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1256 assert (zei->curDatabaseInfo);
1260 zei->curDatabaseInfo->recordCount += adjust_num;
1261 zei->curDatabaseInfo->dirty = 1;
1265 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1269 return zei->runNumber += adjust_num;
1272 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1274 RecordAttr *recordAttr;
1276 if (rec->info[recInfo_attr])
1277 return (RecordAttr *) rec->info[recInfo_attr];
1278 recordAttr = xmalloc (sizeof(*recordAttr));
1279 rec->info[recInfo_attr] = (char *) recordAttr;
1280 rec->size[recInfo_attr] = sizeof(*recordAttr);
1282 recordAttr->recordSize = 0;
1283 recordAttr->recordOffset = 0;
1284 recordAttr->runNumber = zei->runNumber;
1288 static void att_loadset(void *p, const char *n, const char *name)
1290 data1_handle dh = p;
1291 if (!data1_get_attset (dh, name))
1292 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1295 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1297 res_trav(res, "attset", dh, att_loadset);
1301 zebraExplain_addSU adds to AttributeDetails for a database and
1302 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1303 exist for the database.
1305 If the database doesn't exist globally (in TargetInfo) an
1306 AttributeSetInfo must be added (globally).