2 * Copyright (C) 1994-1998, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.9 1998-06-02 12:10:27 adam
8 * Fixed bug related to attributeDetails.
10 * Revision 1.8 1998/05/20 10:12:20 adam
11 * Implemented automatic EXPLAIN database maintenance.
12 * Modified Zebra to work with ASN.1 compiled version of YAZ.
14 * Revision 1.7 1998/03/05 08:45:13 adam
15 * New result set model and modular ranking system. Moved towards
16 * descent server API. System information stored as "SGML" records.
18 * Revision 1.6 1998/02/17 10:29:27 adam
19 * Moved towards 'automatic' EXPLAIN database.
21 * Revision 1.5 1997/10/27 14:33:05 adam
22 * Moved towards generic character mapping depending on "structure"
23 * field in abstract syntax file. Fixed a few memory leaks. Fixed
24 * bug with negative integers when doing searches with relational
27 * Revision 1.4 1997/09/25 14:57:08 adam
30 * Revision 1.3 1996/05/22 08:21:59 adam
31 * Added public ZebDatabaseInfo structure.
33 * Revision 1.2 1996/05/14 06:16:41 adam
34 * Compact use/set bytes used in search service.
36 * Revision 1.1 1996/05/13 14:23:07 adam
37 * Work on compaction of set/use bytes in dictionary.
58 struct zebSUInfo info;
59 struct zebSUInfoB *next;
62 typedef struct zebAccessObjectB *zebAccessObject;
63 struct zebAccessObjectB {
70 typedef struct zebAccessInfoB *zebAccessInfo;
71 struct zebAccessInfoB {
72 zebAccessObject attributeSetIds;
73 zebAccessObject schemas;
77 struct zebSUInfoB *SUInfo;
81 data1_node *data1_tree;
82 } *zebAttributeDetails;
84 struct zebDatabaseInfoB {
85 zebAttributeDetails attributeDetails;
87 data1_node *data1_database;
88 int recordCount; /* records in db */
89 int recordBytes; /* size of records */
90 int sysno; /* sysno of database info */
91 int readFlag; /* 1: read is needed when referenced; 0 if not */
92 int dirty; /* 1: database is dirty: write is needed */
93 struct zebDatabaseInfoB *next;
94 zebAccessInfo accessInfo;
97 struct zebraExplainAttset {
100 struct zebraExplainAttset *next;
103 struct zebraExplainInfo {
110 struct zebraExplainAttset *attsets;
112 data1_node *data1_target;
113 struct zebDatabaseInfoB *databaseInfo;
114 struct zebDatabaseInfoB *curDatabaseInfo;
115 zebAccessInfo accessInfo;
116 char date[15]; /* YYYY MMDD HH MM SS */
117 int (*updateFunc)(void *handle, Record drec, data1_node *n);
121 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
122 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
124 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
126 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
129 static data1_node *data1_search_tag (data1_handle dh, data1_node *n,
132 logf (LOG_DEBUG, "data1_search_tag %s", tag);
133 for (; n; n = n->next)
134 if (n->which == DATA1N_tag && n->u.tag.tag &&
135 !yaz_matchstr (tag, n->u.tag.tag))
137 logf (LOG_DEBUG, " found");
140 logf (LOG_DEBUG, " not found");
144 static data1_node *data1_add_tag (data1_handle dh, data1_node *at,
145 const char *tag, NMEM nmem)
147 data1_node *partag = get_parent_tag(dh, at);
148 data1_node *res = data1_mk_node (dh, nmem);
149 data1_element *e = NULL;
152 res->which = DATA1N_tag;
153 res->u.tag.tag = data1_insert_string (dh, res, nmem, tag);
154 res->u.tag.node_selected = 0;
155 res->u.tag.make_variantlist = 0;
156 res->u.tag.no_data_requested = 0;
157 res->u.tag.get_bytes = -1;
160 e = partag->u.tag.element;
162 data1_getelementbytagname (dh, at->root->u.root.absyn,
164 res->root = at->root;
169 assert (at->last_child);
170 at->last_child->next = res;
172 at->last_child = res;
176 static data1_node *data1_make_tag (data1_handle dh, data1_node *at,
177 const char *tag, NMEM nmem)
179 data1_node *node = data1_search_tag (dh, at->child, tag);
181 node = data1_add_tag (dh, at, tag, nmem);
183 node->child = node->last_child = NULL;
187 static data1_node *data1_add_tagdata_int (data1_handle dh, data1_node *at,
188 const char *tag, int num,
191 data1_node *node_data;
193 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
196 node_data->u.data.what = DATA1I_num;
197 node_data->u.data.data = node_data->lbuf;
198 sprintf (node_data->u.data.data, "%d", num);
199 node_data->u.data.len = strlen (node_data->u.data.data);
203 static data1_node *data1_add_tagdata_oid (data1_handle dh, data1_node *at,
204 const char *tag, Odr_oid *oid,
207 data1_node *node_data;
208 char str[128], *p = str;
211 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
215 for (ii = oid; *ii >= 0; ii++)
219 sprintf (p, "%d", *ii);
222 node_data->u.data.what = DATA1I_oid;
223 node_data->u.data.len = strlen (str);
224 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
229 static data1_node *data1_add_tagdata_text (data1_handle dh, data1_node *at,
230 const char *tag, const char *str,
233 data1_node *node_data;
235 node_data = data1_add_taggeddata (dh, at->root, at, tag, nmem);
238 node_data->u.data.what = DATA1I_text;
239 node_data->u.data.len = strlen (str);
240 node_data->u.data.data = data1_insert_string (dh, node_data, nmem, str);
244 static data1_node *data1_make_tagdata_text (data1_handle dh, data1_node *at,
245 const char *tag, const char *str,
248 data1_node *node = data1_search_tag (dh, at->child, tag);
250 return data1_add_tagdata_text (dh, at, tag, str, nmem);
253 data1_node *node_data = node->child;
254 node_data->u.data.what = DATA1I_text;
255 node_data->u.data.data = node_data->lbuf;
256 strcpy (node_data->u.data.data, str);
257 node_data->u.data.len = strlen (node_data->u.data.data);
262 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
263 struct zebDatabaseInfoB *zdi,
265 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
266 zebAttributeDetails zad,
267 const char *databaseName,
269 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
270 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
274 static Record createRecord (Records records, int *sysno)
279 rec = rec_get (records, *sysno);
280 xfree (rec->info[recInfo_storeData]);
284 rec = rec_new (records);
287 rec->info[recInfo_fileType] =
288 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
289 rec->info[recInfo_databaseName] =
290 rec_strdup ("IR-Explain-1",
291 &rec->size[recInfo_databaseName]);
296 void zebraExplain_close (ZebraExplainInfo zei, int writeFlag,
297 int (*updateH)(Record drec, data1_node *n))
299 struct zebDatabaseInfoB *zdi;
301 logf (LOG_DEBUG, "zebraExplain_close wr=%d", writeFlag);
305 /* write each database info record */
306 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
308 zebraExplain_writeDatabase (zei, zdi, 1);
309 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
310 zdi->databaseName, 1);
312 zebraExplain_writeTarget (zei, 1);
314 assert (zei->accessInfo);
315 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
317 zebraExplain_writeAttributeSet (zei, o, 1);
318 for (o = zei->accessInfo->schemas; o; o = o->next)
321 /* zebraExplain_writeSchema (zei, o, 1); */
324 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
326 zebraExplain_writeDatabase (zei, zdi, 0);
327 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
328 zdi->databaseName, 0);
330 zebraExplain_writeTarget (zei, 0);
333 nmem_destroy (zei->nmem);
337 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
342 for (np = n->child; np; np = np->next)
349 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
351 len = np->child->u.data.len;
354 memcpy (str, np->child->u.data.data, len);
357 oid = odr_getoidbystr_nmem (zei->nmem, str);
359 for (ao = *op; ao; ao = ao->next)
360 if (!oid_oidcmp (oid, ao->oid))
367 ao = nmem_malloc (zei->nmem, sizeof(*ao));
377 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
378 zebAccessInfo *accessInfo)
384 *accessInfo = nmem_malloc (zei->nmem, sizeof(**accessInfo));
385 (*accessInfo)->attributeSetIds = NULL;
386 (*accessInfo)->schemas = NULL;
390 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
392 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
393 zebraExplain_mergeOids (zei, np,
394 &(*accessInfo)->attributeSetIds);
395 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
396 zebraExplain_mergeOids (zei, np,
397 &(*accessInfo)->schemas);
401 ZebraExplainInfo zebraExplain_open (
402 Records records, data1_handle dh,
406 int (*updateFunc)(void *handle, Record drec, data1_node *n))
409 ZebraExplainInfo zei;
410 struct zebDatabaseInfoB **zdip;
414 logf (LOG_DEBUG, "zebraExplain_open wr=%d", writeFlag);
415 zei = xmalloc (sizeof(*zei));
416 zei->updateHandle = updateHandle;
417 zei->updateFunc = updateFunc;
419 zei->curDatabaseInfo = NULL;
420 zei->records = records;
421 zei->nmem = nmem_create ();
427 tm = localtime (&our_time);
428 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
429 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
430 tm->tm_hour, tm->tm_min, tm->tm_sec);
432 zdip = &zei->databaseInfo;
433 trec = rec_get (records, 1); /* get "root" record */
435 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
436 if (trec) /* targetInfo already exists ... */
438 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
440 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
443 data1_pr_tree (zei->dh, zei->data1_target, stderr);
445 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
447 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
450 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
452 node_list = data1_search_tag (zei->dh, node_zebra->child,
454 for (np = node_list->child; np; np = np->next)
456 data1_node *node_name = NULL;
457 data1_node *node_id = NULL;
458 data1_node *node_aid = NULL;
460 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
462 for (np2 = np->child; np2; np2 = np2->next)
464 if (np2->which != DATA1N_tag)
466 if (!strcmp (np2->u.tag.tag, "name"))
467 node_name = np2->child;
468 else if (!strcmp (np2->u.tag.tag, "id"))
469 node_id = np2->child;
470 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
471 node_aid = np2->child;
473 assert (node_id && node_name && node_aid);
475 *zdip = nmem_malloc (zei->nmem, sizeof(**zdip));
477 (*zdip)->readFlag = 1;
479 (*zdip)->data1_database = NULL;
480 (*zdip)->recordCount = 0;
481 (*zdip)->recordBytes = 0;
482 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
484 (*zdip)->databaseName = nmem_malloc (zei->nmem,
485 1+node_name->u.data.len);
486 memcpy ((*zdip)->databaseName, node_name->u.data.data,
487 node_name->u.data.len);
488 (*zdip)->databaseName[node_name->u.data.len] = '\0';
489 (*zdip)->sysno = atoi_n (node_id->u.data.data,
490 node_id->u.data.len);
491 (*zdip)->attributeDetails =
492 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
493 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
494 node_aid->u.data.len);
495 (*zdip)->attributeDetails->readFlag = 1;
496 (*zdip)->attributeDetails->dirty = 0;
497 (*zdip)->attributeDetails->SUInfo = NULL;
499 zdip = &(*zdip)->next;
501 np = data1_search_tag (zei->dh, node_zebra->child,
504 assert (np && np->which == DATA1N_data);
505 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
507 np = data1_search_tag (zei->dh, node_zebra->child,
510 assert (np && np->which == DATA1N_data);
511 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
515 else /* create initial targetInfo */
517 data1_node *node_tgtinfo;
527 data1_read_sgml (zei->dh, zei->nmem,
528 "<explain><targetInfo>TargetInfo\n"
530 "<namedResultSets>1</>\n"
531 "<multipleDBSearch>1</>\n"
532 "<nicknames><name>Zebra</></>\n"
535 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
537 assert (node_tgtinfo);
540 zebraExplain_initCommonInfo (zei, node_tgtinfo);
541 zebraExplain_initAccessInfo (zei, node_tgtinfo);
543 /* write now because we want to be sure about the sysno */
544 trec = rec_new (records);
545 trec->info[recInfo_fileType] =
546 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
547 trec->info[recInfo_databaseName] =
548 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
550 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
551 trec->info[recInfo_storeData] = xmalloc (sgml_len);
552 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
553 trec->size[recInfo_storeData] = sgml_len;
555 rec_put (records, &trec);
559 zebraExplain_newDatabase (zei, "IR-Explain-1");
564 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
565 zebAttributeDetails zad)
568 struct zebSUInfoB **zsuip = &zad->SUInfo;
569 data1_node *node_adinfo, *node_zebra, *node_list, *np;
572 rec = rec_get (zei->records, zad->sysno);
574 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
576 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
578 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
580 node_list = data1_search_tag (zei->dh, node_zebra->child,
582 for (np = node_list->child; np; np = np->next)
584 data1_node *node_set = NULL;
585 data1_node *node_use = NULL;
586 data1_node *node_ordinal = NULL;
588 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
590 for (np2 = np->child; np2; np2 = np2->next)
592 if (np2->which != DATA1N_tag || !np2->child ||
593 np2->child->which != DATA1N_data)
595 if (!strcmp (np2->u.tag.tag, "set"))
596 node_set = np2->child;
597 else if (!strcmp (np2->u.tag.tag, "use"))
598 node_use = np2->child;
599 else if (!strcmp (np2->u.tag.tag, "ordinal"))
600 node_ordinal = np2->child;
602 assert (node_set && node_use && node_ordinal);
604 *zsuip = nmem_malloc (zei->nmem, sizeof(**zsuip));
605 (*zsuip)->info.set = atoi_n (node_set->u.data.data,
606 node_set->u.data.len);
607 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
608 node_use->u.data.len);
609 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
610 node_ordinal->u.data.len);
611 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
612 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
613 zsuip = &(*zsuip)->next;
620 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
621 struct zebDatabaseInfoB *zdi)
624 data1_node *node_dbinfo, *node_zebra, *np;
627 rec = rec_get (zei->records, zdi->sysno);
629 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
631 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
633 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
635 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
637 np = data1_search_tag (zei->dh, node_dbinfo->child,
639 if (np && np->child && np->child->which == DATA1N_data)
640 zdi->recordBytes = atoi_n (np->child->u.data.data,
641 np->child->u.data.len);
642 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
644 (np = data1_search_tag (zei->dh, np->child,
645 "recordCountActual")) &&
646 np->child->which == DATA1N_data)
648 zdi->recordCount = atoi_n (np->child->u.data.data,
649 np->child->u.data.len);
655 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
657 struct zebDatabaseInfoB *zdi;
660 if (zei->curDatabaseInfo &&
661 !strcmp (zei->curDatabaseInfo->databaseName, database))
663 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
665 if (!strcmp (zdi->databaseName, database))
671 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
676 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
678 zebraExplain_readDatabase (zei, zdi);
680 if (zdi->attributeDetails->readFlag)
683 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
685 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
687 zei->curDatabaseInfo = zdi;
691 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
693 data1_node *c = data1_add_tag (zei->dh, n, "commonInfo", zei->nmem);
695 data1_add_tagdata_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
696 data1_add_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
697 data1_add_tagdata_text (zei->dh, c, "languageCode", "EN", zei->nmem);
700 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
702 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
704 data1_make_tagdata_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
707 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
709 data1_node *c = data1_add_tag (zei->dh, n, "accessInfo", zei->nmem);
710 data1_node *d = data1_add_tag (zei->dh, c, "unitSystems", zei->nmem);
711 data1_add_tagdata_text (zei->dh, d, "string", "ISO", zei->nmem);
714 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
715 zebAccessInfo accessInfo)
717 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
723 if ((p = accessInfo->attributeSetIds))
725 d = data1_make_tag (zei->dh, c, "attributeSetIds", zei->nmem);
726 for (; p; p = p->next)
727 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
729 if ((p = accessInfo->schemas))
731 d = data1_make_tag (zei->dh, c, "schemas", zei->nmem);
732 for (; p; p = p->next)
733 data1_add_tagdata_oid (zei->dh, d, "oid", p->oid, zei->nmem);
737 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database)
739 struct zebDatabaseInfoB *zdi;
740 data1_node *node_dbinfo, *node_adinfo;
743 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
746 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
748 if (!strcmp (zdi->databaseName, database))
753 /* it's new really. make it */
754 zdi = nmem_malloc (zei->nmem, sizeof(*zdi));
755 zdi->next = zei->databaseInfo;
756 zei->databaseInfo = zdi;
758 zdi->recordCount = 0;
759 zdi->recordBytes = 0;
761 zdi->databaseName = nmem_strdup (zei->nmem, database);
763 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
768 zdi->data1_database =
769 data1_read_sgml (zei->dh, zei->nmem,
770 "<explain><databaseInfo>DatabaseInfo\n"
773 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
775 assert (node_dbinfo);
777 zebraExplain_initCommonInfo (zei, node_dbinfo);
778 zebraExplain_initAccessInfo (zei, node_dbinfo);
780 data1_add_tagdata_text (zei->dh, node_dbinfo, "name",
781 database, zei->nmem);
783 data1_add_tagdata_text (zei->dh, node_dbinfo, "userFee",
786 data1_add_tagdata_text (zei->dh, node_dbinfo, "available",
790 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
794 zei->curDatabaseInfo = zdi;
796 zdi->attributeDetails =
797 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
798 zdi->attributeDetails->readFlag = 0;
799 zdi->attributeDetails->sysno = 0;
800 zdi->attributeDetails->dirty = 1;
801 zdi->attributeDetails->SUInfo = NULL;
802 zdi->attributeDetails->data1_tree =
803 data1_read_sgml (zei->dh, zei->nmem,
804 "<explain><attributeDetails>AttributeDetails\n"
808 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
810 assert (node_adinfo);
812 zebraExplain_initCommonInfo (zei, node_adinfo);
817 static void writeAttributeValueDetails (ZebraExplainInfo zei,
818 zebAttributeDetails zad,
819 data1_node *node_atvs, data1_attset *attset)
822 struct zebSUInfoB *zsui;
823 int set_ordinal = attset->reference;
824 data1_attset_child *c;
826 for (c = attset->children; c; c = c->next)
827 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
828 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
830 data1_node *node_attvalue, *node_value;
831 if (set_ordinal != zsui->info.set)
833 node_attvalue = data1_add_tag (zei->dh, node_atvs, "attributeValue",
835 node_value = data1_add_tag (zei->dh, node_attvalue, "value",
837 data1_add_tagdata_int (zei->dh, node_value, "numeric",
838 zsui->info.use, zei->nmem);
842 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
843 zebAttributeDetails zad,
844 const char *databaseName,
850 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
851 struct zebSUInfoB *zsui;
859 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
862 drec = createRecord (zei->records, &zad->sysno);
863 assert (zad->data1_tree);
864 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
866 zebraExplain_updateCommonInfo (zei, node_adinfo);
868 data1_add_tagdata_text (zei->dh, node_adinfo, "name",
869 databaseName, zei->nmem);
871 /* extract *searchable* keys from it. We do this here, because
872 record count, etc. is affected */
874 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
876 node_attributesBySet = data1_make_tag (zei->dh, node_adinfo,
877 "attributesBySet", zei->nmem);
881 data1_node *node_asd;
882 data1_attset *attset;
883 int set_ordinal = -1;
884 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
886 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
887 && zsui->info.set > set_min)
888 set_ordinal = zsui->info.set;
892 set_min = set_ordinal;
893 node_asd = data1_add_tag (zei->dh, node_attributesBySet,
894 "attributeSetDetails", zei->nmem);
896 attset = data1_attset_search_id (zei->dh, set_ordinal);
899 zebraExplain_loadAttsets (zei->dh, zei->res);
900 attset = data1_attset_search_id (zei->dh, set_ordinal);
907 oe.proto = PROTO_Z3950;
908 oe.oclass = CLASS_ATTSET;
909 oe.value = set_ordinal;
911 if (oid_ent_to_oid (&oe, oid))
913 data1_node *node_abt, *node_atd, *node_atvs;
914 data1_add_tagdata_oid (zei->dh, node_asd, "oid",
917 node_abt = data1_add_tag (zei->dh, node_asd,
918 "attributesByType", zei->nmem);
919 node_atd = data1_add_tag (zei->dh, node_abt,
920 "attributeTypeDetails", zei->nmem);
921 data1_add_tagdata_int (zei->dh, node_atd,
922 "type", 1, zei->nmem);
923 node_atvs = data1_add_tag (zei->dh, node_atd,
924 "attributeValues", zei->nmem);
925 writeAttributeValueDetails (zei, zad, node_atvs, attset);
929 /* zebra info (private) */
930 node_zebra = data1_make_tag (zei->dh, node_adinfo,
931 "zebraInfo", zei->nmem);
932 node_list = data1_make_tag (zei->dh, node_zebra,
933 "attrlist", zei->nmem);
934 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
936 data1_node *node_attr;
937 node_attr = data1_add_tag (zei->dh, node_list,
939 data1_add_tagdata_int (zei->dh, node_attr, "set",
940 zsui->info.set, zei->nmem);
941 data1_add_tagdata_int (zei->dh, node_attr, "use",
942 zsui->info.use, zei->nmem);
943 data1_add_tagdata_int (zei->dh, node_attr, "ordinal",
944 zsui->info.ordinal, zei->nmem);
946 /* convert to "SGML" and write it */
948 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
950 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
952 drec->info[recInfo_storeData] = xmalloc (sgml_len);
953 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
954 drec->size[recInfo_storeData] = sgml_len;
956 rec_put (zei->records, &drec);
959 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
960 struct zebDatabaseInfoB *zdi,
966 data1_node *node_dbinfo, *node_count, *node_zebra;
973 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
975 drec = createRecord (zei->records, &zdi->sysno);
976 assert (zdi->data1_database);
977 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
980 zebraExplain_updateCommonInfo (zei, node_dbinfo);
981 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
983 /* extract *searchable* keys from it. We do this here, because
984 record count, etc. is affected */
986 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
988 node_count = data1_make_tag (zei->dh, node_dbinfo,
989 "recordCount", zei->nmem);
990 data1_add_tagdata_int (zei->dh, node_count, "recordCountActual",
991 zdi->recordCount, zei->nmem);
993 /* zebra info (private) */
994 node_zebra = data1_make_tag (zei->dh, node_dbinfo,
995 "zebraInfo", zei->nmem);
996 data1_add_tagdata_int (zei->dh, node_zebra,
997 "recordBytes", zdi->recordBytes, zei->nmem);
998 /* convert to "SGML" and write it */
1000 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1002 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1004 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1005 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1006 drec->size[recInfo_storeData] = sgml_len;
1008 rec_put (zei->records, &drec);
1011 static void writeAttributeValues (ZebraExplainInfo zei,
1012 data1_node *node_values,
1013 data1_attset *attset)
1016 data1_attset_child *c;
1021 for (c = attset->children; c; c = c->next)
1022 writeAttributeValues (zei, node_values, c->child);
1023 for (atts = attset->atts; atts; atts = atts->next)
1025 data1_node *node_value;
1027 node_value = data1_add_tag (zei->dh, node_values, "attributeValue",
1029 data1_add_tagdata_text (zei->dh, node_value, "name",
1030 atts->name, zei->nmem);
1031 node_value = data1_add_tag (zei->dh, node_value, "value", zei->nmem);
1032 data1_add_tagdata_int (zei->dh, node_value, "numeric",
1033 atts->value, zei->nmem);
1038 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1045 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1046 data1_node *node_values;
1047 struct oident *entp;
1048 struct data1_attset *attset = NULL;
1050 if ((entp = oid_getentbyoid (o->oid)))
1051 attset = data1_attset_search_id (zei->dh, entp->value);
1054 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1055 attset ? attset->name : "<unknown>");
1058 drec = createRecord (zei->records, &o->sysno);
1060 data1_read_sgml (zei->dh, zei->nmem,
1061 "<explain><attributeSetInfo>AttributeSetInfo\n"
1064 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1065 "attributeSetInfo");
1067 zebraExplain_initCommonInfo (zei, node_attinfo);
1068 zebraExplain_updateCommonInfo (zei, node_attinfo);
1070 data1_add_tagdata_oid (zei->dh, node_attinfo,
1071 "oid", o->oid, zei->nmem);
1072 if (attset && attset->name)
1073 data1_add_tagdata_text (zei->dh, node_attinfo,
1074 "name", attset->name, zei->nmem);
1076 node_attributes = data1_make_tag (zei->dh, node_attinfo,
1077 "attributes", zei->nmem);
1078 node_atttype = data1_make_tag (zei->dh, node_attributes,
1079 "attributeType", zei->nmem);
1080 data1_add_tagdata_text (zei->dh, node_atttype,
1081 "name", "Use", zei->nmem);
1082 data1_add_tagdata_text (zei->dh, node_atttype,
1083 "description", "Use Attribute", zei->nmem);
1084 data1_add_tagdata_int (zei->dh, node_atttype,
1085 "type", 1, zei->nmem);
1086 node_values = data1_add_tag (zei->dh, node_atttype,
1087 "attributeValues", zei->nmem);
1089 writeAttributeValues (zei, node_values, attset);
1091 /* extract *searchable* keys from it. We do this here, because
1092 record count, etc. is affected */
1094 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1095 /* convert to "SGML" and write it */
1097 data1_pr_tree (zei->dh, node_root, stderr);
1099 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1100 drec->info[recInfo_storeData] = xmalloc (sgml_len);
1101 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1102 drec->size[recInfo_storeData] = sgml_len;
1104 rec_put (zei->records, &drec);
1107 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1109 struct zebDatabaseInfoB *zdi;
1110 data1_node *node_tgtinfo, *node_list, *node_zebra;
1119 trec = rec_get (zei->records, 1);
1120 xfree (trec->info[recInfo_storeData]);
1122 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1124 assert (node_tgtinfo);
1126 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1127 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1129 /* convert to "SGML" and write it */
1131 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1133 node_zebra = data1_make_tag (zei->dh, node_tgtinfo,
1134 "zebraInfo", zei->nmem);
1135 data1_add_tagdata_text (zei->dh, node_zebra, "version",
1136 ZEBRAVER, zei->nmem);
1137 node_list = data1_add_tag (zei->dh, node_zebra,
1138 "databaseList", zei->nmem);
1139 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1141 data1_node *node_db;
1142 node_db = data1_add_tag (zei->dh, node_list,
1143 "database", zei->nmem);
1144 data1_add_tagdata_text (zei->dh, node_db, "name",
1145 zdi->databaseName, zei->nmem);
1146 data1_add_tagdata_int (zei->dh, node_db, "id",
1147 zdi->sysno, zei->nmem);
1148 data1_add_tagdata_int (zei->dh, node_db, "attributeDetailsId",
1149 zdi->attributeDetails->sysno, zei->nmem);
1151 data1_add_tagdata_int (zei->dh, node_zebra, "ordinalSU",
1152 zei->ordinalSU, zei->nmem);
1154 data1_add_tagdata_int (zei->dh, node_zebra, "runNumber",
1155 zei->runNumber, zei->nmem);
1158 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1160 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1162 trec->info[recInfo_storeData] = xmalloc (sgml_len);
1163 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1164 trec->size[recInfo_storeData] = sgml_len;
1166 rec_put (zei->records, &trec);
1169 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1171 struct zebSUInfoB *zsui;
1173 assert (zei->curDatabaseInfo);
1174 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1175 zsui; zsui=zsui->next)
1176 if (zsui->info.use == use && zsui->info.set == set)
1177 return zsui->info.ordinal;
1181 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1182 zebAccessObject *op,
1187 for (ao = *op; ao; ao = ao->next)
1188 if (!oid_oidcmp (oid, ao->oid))
1192 ao = nmem_malloc (zei->nmem, sizeof(*ao));
1195 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1202 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1207 oe.proto = PROTO_Z3950;
1208 oe.oclass = CLASS_ATTSET;
1211 if (oid_ent_to_oid (&oe, oid))
1213 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1214 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1215 accessInfo->attributeSetIds, oid);
1219 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1221 struct zebSUInfoB *zsui;
1223 assert (zei->curDatabaseInfo);
1224 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1225 zsui; zsui=zsui->next)
1226 if (zsui->info.use == use && zsui->info.set == set)
1228 zebraExplain_addAttributeSet (zei, set);
1229 zsui = nmem_malloc (zei->nmem, sizeof(*zsui));
1230 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1231 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1232 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1234 zsui->info.set = set;
1235 zsui->info.use = use;
1236 zsui->info.ordinal = (zei->ordinalSU)++;
1237 return zsui->info.ordinal;
1240 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1242 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1243 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1244 accessInfo->schemas, oid);
1247 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1249 assert (zei->curDatabaseInfo);
1253 zei->curDatabaseInfo->recordBytes += adjust_num;
1254 zei->curDatabaseInfo->dirty = 1;
1258 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1260 assert (zei->curDatabaseInfo);
1264 zei->curDatabaseInfo->recordCount += adjust_num;
1265 zei->curDatabaseInfo->dirty = 1;
1269 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1273 return zei->runNumber += adjust_num;
1276 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1278 RecordAttr *recordAttr;
1280 if (rec->info[recInfo_attr])
1281 return (RecordAttr *) rec->info[recInfo_attr];
1282 recordAttr = xmalloc (sizeof(*recordAttr));
1283 rec->info[recInfo_attr] = (char *) recordAttr;
1284 rec->size[recInfo_attr] = sizeof(*recordAttr);
1286 recordAttr->recordSize = 0;
1287 recordAttr->recordOffset = 0;
1288 recordAttr->runNumber = zei->runNumber;
1292 static void att_loadset(void *p, const char *n, const char *name)
1294 data1_handle dh = p;
1295 if (!data1_get_attset (dh, name))
1296 logf (LOG_WARN, "Couldn't load attribute set %s", name);
1299 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1301 res_trav(res, "attset", dh, att_loadset);
1305 zebraExplain_addSU adds to AttributeDetails for a database and
1306 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1307 exist for the database.
1309 If the database doesn't exist globally (in TargetInfo) an
1310 AttributeSetInfo must be added (globally).