2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.30 2002-05-13 14:13:43 adam Exp $
26 struct zebSUInfo info;
27 struct zebSUInfoB *next;
30 typedef struct zebAccessObjectB *zebAccessObject;
31 struct zebAccessObjectB {
38 typedef struct zebAccessInfoB *zebAccessInfo;
39 struct zebAccessInfoB {
40 zebAccessObject attributeSetIds;
41 zebAccessObject schemas;
45 struct zebSUInfoB *SUInfo;
49 data1_node *data1_tree;
50 } *zebAttributeDetails;
52 struct zebDatabaseInfoB {
53 zebAttributeDetails attributeDetails;
55 data1_node *data1_database;
56 int recordCount; /* records in db */
57 int recordBytes; /* size of records */
58 int sysno; /* sysno of database info */
59 int readFlag; /* 1: read is needed when referenced; 0 if not */
60 int dirty; /* 1: database is dirty: write is needed */
61 struct zebDatabaseInfoB *next;
62 zebAccessInfo accessInfo;
65 struct zebraExplainAttset {
68 struct zebraExplainAttset *next;
71 struct zebraCategoryListInfo {
74 data1_node *data1_categoryList;
77 struct zebraExplainInfo {
85 struct zebraExplainAttset *attsets;
87 data1_node *data1_target;
88 struct zebraCategoryListInfo *categoryList;
89 struct zebDatabaseInfoB *databaseInfo;
90 struct zebDatabaseInfoB *curDatabaseInfo;
91 zebAccessInfo accessInfo;
92 char date[15]; /* YYYY MMDD HH MM SS */
93 int (*updateFunc)(void *handle, Record drec, data1_node *n);
97 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n);
98 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n);
100 static data1_node *read_sgml_rec (data1_handle dh, NMEM nmem, Record rec)
102 return data1_read_sgml (dh, nmem, rec->info[recInfo_storeData]);
105 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
106 struct zebDatabaseInfoB *zdi,
108 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
109 zebAttributeDetails zad,
110 const char *databaseName,
112 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush);
113 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
116 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
117 struct zebraCategoryListInfo *zcl,
121 static Record createRecord (Records records, int *sysno)
126 rec = rec_get (records, *sysno);
127 xfree (rec->info[recInfo_storeData]);
131 rec = rec_new (records);
134 rec->info[recInfo_fileType] =
135 rec_strdup ("grs.sgml", &rec->size[recInfo_fileType]);
136 rec->info[recInfo_databaseName] =
137 rec_strdup ("IR-Explain-1",
138 &rec->size[recInfo_databaseName]);
143 void zebraExplain_flush (ZebraExplainInfo zei, void *handle)
147 zei->updateHandle = handle;
150 struct zebDatabaseInfoB *zdi;
153 /* write each database info record */
154 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
156 zebraExplain_writeDatabase (zei, zdi, 1);
157 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
158 zdi->databaseName, 1);
160 zebraExplain_writeTarget (zei, 1);
161 zebraExplain_writeCategoryList (zei,
164 assert (zei->accessInfo);
165 for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
167 zebraExplain_writeAttributeSet (zei, o, 1);
168 for (o = zei->accessInfo->schemas; o; o = o->next)
171 /* zebraExplain_writeSchema (zei, o, 1); */
174 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
176 zebraExplain_writeDatabase (zei, zdi, 0);
177 zebraExplain_writeAttributeDetails (zei, zdi->attributeDetails,
178 zdi->databaseName, 0);
180 zebraExplain_writeTarget (zei, 0);
184 void zebraExplain_close (ZebraExplainInfo zei)
187 yaz_log (LOG_LOG, "zebraExplain_close");
191 zebraExplain_flush (zei, zei->updateHandle);
192 nmem_destroy (zei->nmem);
195 void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
200 for (np = n->child; np; np = np->next)
207 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "oid"))
209 len = np->child->u.data.len;
212 memcpy (str, np->child->u.data.data, len);
215 oid = odr_getoidbystr_nmem (zei->nmem, str);
217 for (ao = *op; ao; ao = ao->next)
218 if (!oid_oidcmp (oid, ao->oid))
225 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
235 void zebraExplain_mergeAccessInfo (ZebraExplainInfo zei, data1_node *n,
236 zebAccessInfo *accessInfo)
242 *accessInfo = (zebAccessInfo)
243 nmem_malloc (zei->nmem, sizeof(**accessInfo));
244 (*accessInfo)->attributeSetIds = NULL;
245 (*accessInfo)->schemas = NULL;
249 if (!(n = data1_search_tag (zei->dh, n->child, "accessInfo")))
251 if ((np = data1_search_tag (zei->dh, n->child, "attributeSetIds")))
252 zebraExplain_mergeOids (zei, np,
253 &(*accessInfo)->attributeSetIds);
254 if ((np = data1_search_tag (zei->dh, n->child, "schemas")))
255 zebraExplain_mergeOids (zei, np,
256 &(*accessInfo)->schemas);
260 ZebraExplainInfo zebraExplain_open (
261 Records records, data1_handle dh,
265 int (*updateFunc)(void *handle, Record drec, data1_node *n))
268 ZebraExplainInfo zei;
269 struct zebDatabaseInfoB **zdip;
272 NMEM nmem = nmem_create ();
275 logf (LOG_LOG, "zebraExplain_open wr=%d", writeFlag);
277 zei = (ZebraExplainInfo) nmem_malloc (nmem, sizeof(*zei));
278 zei->write_flag = writeFlag;
279 zei->updateHandle = updateHandle;
280 zei->updateFunc = updateFunc;
282 zei->curDatabaseInfo = NULL;
283 zei->records = records;
288 zei->categoryList = (struct zebraCategoryListInfo *)
289 nmem_malloc (zei->nmem, sizeof(*zei->categoryList));
290 zei->categoryList->sysno = 0;
291 zei->categoryList->dirty = 0;
292 zei->categoryList->data1_categoryList = NULL;
295 tm = localtime (&our_time);
296 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
297 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
298 tm->tm_hour, tm->tm_min, tm->tm_sec);
300 zdip = &zei->databaseInfo;
301 trec = rec_get (records, 1); /* get "root" record */
306 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
307 if (trec) /* targetInfo already exists ... */
309 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
311 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
313 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
315 if (!zei->data1_target)
318 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
319 nmem_destroy (zei->nmem);
323 data1_pr_tree (zei->dh, zei->data1_target, stderr);
325 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
327 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
330 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
335 node_list = data1_search_tag (zei->dh, node_zebra->child,
338 np = node_list->child;
340 for (; np; np = np->next)
342 data1_node *node_name = NULL;
343 data1_node *node_id = NULL;
344 data1_node *node_aid = NULL;
346 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
348 for (np2 = np->child; np2; np2 = np2->next)
350 if (np2->which != DATA1N_tag)
352 if (!strcmp (np2->u.tag.tag, "name"))
353 node_name = np2->child;
354 else if (!strcmp (np2->u.tag.tag, "id"))
355 node_id = np2->child;
356 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
357 node_aid = np2->child;
359 assert (node_id && node_name && node_aid);
361 *zdip = (struct zebDatabaseInfoB *)
362 nmem_malloc (zei->nmem, sizeof(**zdip));
363 (*zdip)->readFlag = 1;
365 (*zdip)->data1_database = NULL;
366 (*zdip)->recordCount = 0;
367 (*zdip)->recordBytes = 0;
368 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
370 (*zdip)->databaseName = (char *)
371 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
372 memcpy ((*zdip)->databaseName, node_name->u.data.data,
373 node_name->u.data.len);
374 (*zdip)->databaseName[node_name->u.data.len] = '\0';
375 (*zdip)->sysno = atoi_n (node_id->u.data.data,
376 node_id->u.data.len);
377 (*zdip)->attributeDetails = (zebAttributeDetails)
378 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
379 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
380 node_aid->u.data.len);
381 (*zdip)->attributeDetails->readFlag = 1;
382 (*zdip)->attributeDetails->dirty = 0;
383 (*zdip)->attributeDetails->SUInfo = NULL;
385 zdip = &(*zdip)->next;
389 np = data1_search_tag (zei->dh, node_zebra->child,
392 assert (np && np->which == DATA1N_data);
393 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
395 np = data1_search_tag (zei->dh, node_zebra->child,
398 assert (np && np->which == DATA1N_data);
399 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
400 yaz_log (LOG_LOG, "READ runnumber = %d", zei->runNumber);
405 else /* create initial targetInfo */
407 data1_node *node_tgtinfo;
416 data1_read_sgml (zei->dh, zei->nmem,
417 "<explain><targetInfo>TargetInfo\n"
419 "<namedResultSets>1</>\n"
420 "<multipleDBSearch>1</>\n"
421 "<nicknames><name>Zebra</></>\n"
423 if (!zei->data1_target)
425 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
426 nmem_destroy (zei->nmem);
429 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
431 assert (node_tgtinfo);
433 zebraExplain_initCommonInfo (zei, node_tgtinfo);
434 zebraExplain_initAccessInfo (zei, node_tgtinfo);
436 /* write now because we want to be sure about the sysno */
437 trec = rec_new (records);
438 trec->info[recInfo_fileType] =
439 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
440 trec->info[recInfo_databaseName] =
441 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
443 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
444 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
445 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
446 trec->size[recInfo_storeData] = sgml_len;
448 rec_put (records, &trec);
452 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
454 if (!zei->categoryList->dirty)
456 struct zebraCategoryListInfo *zcl = zei->categoryList;
460 zcl->data1_categoryList =
461 data1_read_sgml (zei->dh, zei->nmem,
462 "<explain><categoryList>CategoryList\n"
465 if (zcl->data1_categoryList)
467 assert (zcl->data1_categoryList->child);
468 node_cl = data1_search_tag (zei->dh,
469 zcl->data1_categoryList->child,
472 zebraExplain_initCommonInfo (zei, node_cl);
479 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
480 zebAttributeDetails zad)
483 struct zebSUInfoB **zsuip = &zad->SUInfo;
484 data1_node *node_adinfo, *node_zebra, *node_list, *np;
487 rec = rec_get (zei->records, zad->sysno);
489 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
491 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
493 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
495 node_list = data1_search_tag (zei->dh, node_zebra->child,
497 for (np = node_list->child; np; np = np->next)
499 data1_node *node_set = NULL;
500 data1_node *node_use = NULL;
501 data1_node *node_ordinal = NULL;
506 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
508 for (np2 = np->child; np2; np2 = np2->next)
510 if (np2->which != DATA1N_tag || !np2->child ||
511 np2->child->which != DATA1N_data)
513 if (!strcmp (np2->u.tag.tag, "set"))
514 node_set = np2->child;
515 else if (!strcmp (np2->u.tag.tag, "use"))
516 node_use = np2->child;
517 else if (!strcmp (np2->u.tag.tag, "ordinal"))
518 node_ordinal = np2->child;
520 assert (node_set && node_use && node_ordinal);
522 oid_str_len = node_set->u.data.len;
523 if (oid_str_len >= (int) sizeof(oid_str))
524 oid_str_len = sizeof(oid_str)-1;
525 memcpy (oid_str, node_set->u.data.data, oid_str_len);
526 oid_str[oid_str_len] = '\0';
528 *zsuip = (struct zebSUInfoB *)
529 nmem_malloc (zei->nmem, sizeof(**zsuip));
530 (*zsuip)->info.set = oid_getvalbyname (oid_str);
532 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
533 node_use->u.data.len);
534 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
535 node_ordinal->u.data.len);
536 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
537 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
538 zsuip = &(*zsuip)->next;
545 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
546 struct zebDatabaseInfoB *zdi)
549 data1_node *node_dbinfo, *node_zebra, *np;
552 rec = rec_get (zei->records, zdi->sysno);
554 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
556 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
558 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
560 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
563 && (np = data1_search_tag (zei->dh, node_zebra->child,
565 && np->child && np->child->which == DATA1N_data)
566 zdi->recordBytes = atoi_n (np->child->u.data.data,
567 np->child->u.data.len);
568 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
570 (np = data1_search_tag (zei->dh, np->child,
571 "recordCountActual")) &&
572 np->child->which == DATA1N_data)
574 zdi->recordCount = atoi_n (np->child->u.data.data,
575 np->child->u.data.len);
581 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
583 struct zebDatabaseInfoB *zdi;
584 const char *database_n = strrchr (database, '/');
589 database_n = database;
592 if (zei->curDatabaseInfo &&
593 !strcmp (zei->curDatabaseInfo->databaseName, database))
595 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
597 if (!strcmp (zdi->databaseName, database_n))
603 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
608 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
610 zebraExplain_readDatabase (zei, zdi);
612 if (zdi->attributeDetails->readFlag)
615 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
617 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
619 zei->curDatabaseInfo = zdi;
623 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
625 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
626 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
627 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
628 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
631 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
633 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
635 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
639 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
641 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
642 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
643 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
646 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
647 zebAccessInfo accessInfo)
649 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
655 data1_pr_tree (zei->dh, n, stdout);
660 if ((p = accessInfo->attributeSetIds))
662 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
663 for (; p; p = p->next)
664 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
666 if ((p = accessInfo->schemas))
668 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
669 for (; p; p = p->next)
670 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
674 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
675 int explain_database)
677 struct zebDatabaseInfoB *zdi;
678 data1_node *node_dbinfo, *node_adinfo;
679 const char *database_n = strrchr (database, '/');
684 database_n = database;
687 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
690 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
692 if (!strcmp (zdi->databaseName, database_n))
697 /* it's new really. make it */
698 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
699 zdi->next = zei->databaseInfo;
700 zei->databaseInfo = zdi;
702 zdi->recordCount = 0;
703 zdi->recordBytes = 0;
705 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
707 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
712 zdi->data1_database =
713 data1_read_sgml (zei->dh, zei->nmem,
714 "<explain><databaseInfo>DatabaseInfo\n"
716 if (!zdi->data1_database)
719 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
721 assert (node_dbinfo);
723 zebraExplain_initCommonInfo (zei, node_dbinfo);
724 zebraExplain_initAccessInfo (zei, node_dbinfo);
726 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
727 database, zei->nmem);
729 if (explain_database)
730 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
733 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
736 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
740 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
744 zei->curDatabaseInfo = zdi;
746 zdi->attributeDetails = (zebAttributeDetails)
747 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
748 zdi->attributeDetails->readFlag = 0;
749 zdi->attributeDetails->sysno = 0;
750 zdi->attributeDetails->dirty = 1;
751 zdi->attributeDetails->SUInfo = NULL;
752 zdi->attributeDetails->data1_tree =
753 data1_read_sgml (zei->dh, zei->nmem,
754 "<explain><attributeDetails>AttributeDetails\n"
758 data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree->child,
760 assert (node_adinfo);
762 zebraExplain_initCommonInfo (zei, node_adinfo);
767 static void writeAttributeValueDetails (ZebraExplainInfo zei,
768 zebAttributeDetails zad,
769 data1_node *node_atvs, data1_attset *attset)
772 struct zebSUInfoB *zsui;
773 int set_ordinal = attset->reference;
774 data1_attset_child *c;
776 for (c = attset->children; c; c = c->next)
777 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
778 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
780 data1_node *node_attvalue, *node_value;
781 if (set_ordinal != zsui->info.set)
783 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
784 0 /* attr */, node_atvs);
785 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
786 0 /* attr */, node_attvalue);
787 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
788 zsui->info.use, zei->nmem);
792 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
793 struct zebraCategoryListInfo *zcl,
800 data1_node *node_ci, *node_categoryList;
802 static char *category[] = {
814 node_categoryList = zcl->data1_categoryList;
817 logf (LOG_LOG, "zebraExplain_writeCategoryList");
820 drec = createRecord (zei->records, &sysno);
822 node_ci = data1_search_tag (zei->dh, node_categoryList->child,
825 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
829 for (i = 0; category[i]; i++)
831 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
832 0 /* attr */, node_ci);
834 data1_mk_tag_data_text (zei->dh, node_cat, "name",
835 category[i], zei->nmem);
837 /* extract *searchable* keys from it. We do this here, because
838 record count, etc. is affected */
840 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
842 /* convert to "SGML" and write it */
844 data1_pr_tree (zei->dh, node_categoryList, stderr);
846 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
847 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
848 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
849 drec->size[recInfo_storeData] = sgml_len;
851 rec_put (zei->records, &drec);
854 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
855 zebAttributeDetails zad,
856 const char *databaseName,
862 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
863 struct zebSUInfoB *zsui;
871 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
874 drec = createRecord (zei->records, &zad->sysno);
875 assert (zad->data1_tree);
876 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
878 zebraExplain_updateCommonInfo (zei, node_adinfo);
880 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
881 databaseName, zei->nmem);
883 /* extract *searchable* keys from it. We do this here, because
884 record count, etc. is affected */
886 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
888 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
889 "attributesBySet", node_adinfo);
893 data1_node *node_asd;
894 data1_attset *attset;
895 int set_ordinal = -1;
896 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
898 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
899 && zsui->info.set > set_min)
900 set_ordinal = zsui->info.set;
904 set_min = set_ordinal;
905 node_asd = data1_mk_tag (zei->dh, zei->nmem,
906 "attributeSetDetails",
907 0 /* attr */, node_attributesBySet);
909 attset = data1_attset_search_id (zei->dh, set_ordinal);
912 zebraExplain_loadAttsets (zei->dh, zei->res);
913 attset = data1_attset_search_id (zei->dh, set_ordinal);
920 oe.proto = PROTO_Z3950;
921 oe.oclass = CLASS_ATTSET;
922 oe.value = (enum oid_value) set_ordinal;
924 if (oid_ent_to_oid (&oe, oid))
926 data1_node *node_abt, *node_atd, *node_atvs;
927 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
930 node_abt = data1_mk_tag (zei->dh, zei->nmem,
932 0 /*attr */, node_asd);
933 node_atd = data1_mk_tag (zei->dh, zei->nmem,
934 "attributeTypeDetails",
935 0 /* attr */, node_abt);
936 data1_mk_tag_data_int (zei->dh, node_atd,
937 "type", 1, zei->nmem);
938 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
940 0 /* attr */, node_atd);
941 writeAttributeValueDetails (zei, zad, node_atvs, attset);
945 /* zebra info (private) */
946 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
947 "zebraInfo", node_adinfo);
948 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
949 "attrlist", node_zebra);
950 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
952 struct oident oident;
954 data1_node *node_attr;
956 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
959 oident.proto = PROTO_Z3950;
960 oident.oclass = CLASS_ATTSET;
961 oident.value = (enum oid_value) zsui->info.set;
962 oid_ent_to_oid (&oident, oid);
964 data1_mk_tag_data_text (zei->dh, node_attr, "set",
965 oident.desc, zei->nmem);
966 data1_mk_tag_data_int (zei->dh, node_attr, "use",
967 zsui->info.use, zei->nmem);
968 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
969 zsui->info.ordinal, zei->nmem);
971 /* convert to "SGML" and write it */
973 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
975 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
977 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
978 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
979 drec->size[recInfo_storeData] = sgml_len;
981 rec_put (zei->records, &drec);
984 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
985 struct zebDatabaseInfoB *zdi,
991 data1_node *node_dbinfo, *node_count, *node_zebra;
998 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1000 drec = createRecord (zei->records, &zdi->sysno);
1001 assert (zdi->data1_database);
1002 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
1005 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1006 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1008 /* extract *searchable* keys from it. We do this here, because
1009 record count, etc. is affected */
1011 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1013 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1014 "recordCount", node_dbinfo);
1015 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1016 zdi->recordCount, zei->nmem);
1018 /* zebra info (private) */
1019 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1020 "zebraInfo", node_dbinfo);
1021 data1_mk_tag_data_int (zei->dh, node_zebra,
1022 "recordBytes", zdi->recordBytes, zei->nmem);
1023 /* convert to "SGML" and write it */
1025 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1027 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1029 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1030 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1031 drec->size[recInfo_storeData] = sgml_len;
1033 rec_put (zei->records, &drec);
1036 static void writeAttributeValues (ZebraExplainInfo zei,
1037 data1_node *node_values,
1038 data1_attset *attset)
1041 data1_attset_child *c;
1046 for (c = attset->children; c; c = c->next)
1047 writeAttributeValues (zei, node_values, c->child);
1048 for (atts = attset->atts; atts; atts = atts->next)
1050 data1_node *node_value;
1052 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1053 0 /* attr */, node_values);
1054 data1_mk_tag_data_text (zei->dh, node_value, "name",
1055 atts->name, zei->nmem);
1056 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1057 0 /* attr */, node_value);
1058 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1059 atts->value, zei->nmem);
1064 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1071 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1072 data1_node *node_values;
1073 struct oident *entp;
1074 struct data1_attset *attset = NULL;
1076 if ((entp = oid_getentbyoid (o->oid)))
1077 attset = data1_attset_search_id (zei->dh, entp->value);
1080 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1081 attset ? attset->name : "<unknown>");
1084 drec = createRecord (zei->records, &o->sysno);
1086 data1_read_sgml (zei->dh, zei->nmem,
1087 "<explain><attributeSetInfo>AttributeSetInfo\n"
1090 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1091 "attributeSetInfo");
1093 zebraExplain_initCommonInfo (zei, node_attinfo);
1094 zebraExplain_updateCommonInfo (zei, node_attinfo);
1096 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1097 "oid", o->oid, zei->nmem);
1098 if (attset && attset->name)
1099 data1_mk_tag_data_text (zei->dh, node_attinfo,
1100 "name", attset->name, zei->nmem);
1102 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1103 "attributes", node_attinfo);
1104 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1105 "attributeType", node_attributes);
1106 data1_mk_tag_data_text (zei->dh, node_atttype,
1107 "name", "Use", zei->nmem);
1108 data1_mk_tag_data_text (zei->dh, node_atttype,
1109 "description", "Use Attribute", zei->nmem);
1110 data1_mk_tag_data_int (zei->dh, node_atttype,
1111 "type", 1, zei->nmem);
1112 node_values = data1_mk_tag (zei->dh, zei->nmem,
1113 "attributeValues", 0 /* attr */, node_atttype);
1115 writeAttributeValues (zei, node_values, attset);
1117 /* extract *searchable* keys from it. We do this here, because
1118 record count, etc. is affected */
1120 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1121 /* convert to "SGML" and write it */
1123 data1_pr_tree (zei->dh, node_root, stderr);
1125 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1126 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1127 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1128 drec->size[recInfo_storeData] = sgml_len;
1130 rec_put (zei->records, &drec);
1133 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1135 struct zebDatabaseInfoB *zdi;
1136 data1_node *node_tgtinfo, *node_list, *node_zebra;
1145 trec = rec_get (zei->records, 1);
1146 xfree (trec->info[recInfo_storeData]);
1148 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1150 assert (node_tgtinfo);
1152 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1153 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1155 /* convert to "SGML" and write it */
1157 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1159 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1160 "zebraInfo", node_tgtinfo);
1161 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1162 ZEBRAVER, zei->nmem);
1163 node_list = data1_mk_tag (zei->dh, zei->nmem,
1164 "databaseList", 0 /* attr */, node_zebra);
1165 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1167 data1_node *node_db;
1168 node_db = data1_mk_tag (zei->dh, zei->nmem,
1169 "database", 0 /* attr */, node_list);
1170 data1_mk_tag_data_text (zei->dh, node_db, "name",
1171 zdi->databaseName, zei->nmem);
1172 data1_mk_tag_data_int (zei->dh, node_db, "id",
1173 zdi->sysno, zei->nmem);
1174 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1175 zdi->attributeDetails->sysno, zei->nmem);
1177 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1178 zei->ordinalSU, zei->nmem);
1180 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1181 zei->runNumber, zei->nmem);
1184 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1186 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1188 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1189 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1190 trec->size[recInfo_storeData] = sgml_len;
1192 rec_put (zei->records, &trec);
1195 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1197 struct zebSUInfoB *zsui;
1199 assert (zei->curDatabaseInfo);
1200 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1201 zsui; zsui=zsui->next)
1202 if (zsui->info.use == use && zsui->info.set == set)
1203 return zsui->info.ordinal;
1207 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1208 const char **db, int *set, int *use)
1210 struct zebDatabaseInfoB *zdb;
1211 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1213 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1214 for ( ;zsui; zsui = zsui->next)
1215 if (zsui->info.ordinal == ord)
1217 *db = zdb->databaseName;
1218 *set = zsui->info.set;
1219 *use = zsui->info.use;
1226 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1227 zebAccessObject *op,
1232 for (ao = *op; ao; ao = ao->next)
1233 if (!oid_oidcmp (oid, ao->oid))
1237 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1240 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1247 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1252 oe.proto = PROTO_Z3950;
1253 oe.oclass = CLASS_ATTSET;
1254 oe.value = (enum oid_value) set;
1256 if (oid_ent_to_oid (&oe, oid))
1258 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1259 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1260 accessInfo->attributeSetIds, oid);
1264 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1266 struct zebSUInfoB *zsui;
1268 assert (zei->curDatabaseInfo);
1269 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1270 zsui; zsui=zsui->next)
1271 if (zsui->info.use == use && zsui->info.set == set)
1273 zebraExplain_addAttributeSet (zei, set);
1274 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1275 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1276 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1277 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1279 zsui->info.set = set;
1280 zsui->info.use = use;
1281 zsui->info.ordinal = (zei->ordinalSU)++;
1282 return zsui->info.ordinal;
1285 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1287 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1288 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1289 accessInfo->schemas, oid);
1292 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1294 assert (zei->curDatabaseInfo);
1298 zei->curDatabaseInfo->recordBytes += adjust_num;
1299 zei->curDatabaseInfo->dirty = 1;
1303 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1305 assert (zei->curDatabaseInfo);
1309 zei->curDatabaseInfo->recordCount += adjust_num;
1310 zei->curDatabaseInfo->dirty = 1;
1314 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1319 yaz_log (LOG_LOG, "zinfo run number=%d", zei->runNumber+adjust_num);
1321 return zei->runNumber += adjust_num;
1324 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1326 RecordAttr *recordAttr;
1328 if (rec->info[recInfo_attr])
1329 return (RecordAttr *) rec->info[recInfo_attr];
1330 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1331 rec->info[recInfo_attr] = (char *) recordAttr;
1332 rec->size[recInfo_attr] = sizeof(*recordAttr);
1334 recordAttr->recordSize = 0;
1335 recordAttr->recordOffset = 0;
1336 recordAttr->runNumber = zei->runNumber;
1340 static void att_loadset(void *p, const char *n, const char *name)
1342 data1_handle dh = (data1_handle) p;
1343 if (!data1_get_attset (dh, name))
1344 logf (LOG_WARN, "Directive attset failed for %s", name);
1347 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1349 res_trav(res, "attset", dh, att_loadset);
1353 zebraExplain_addSU adds to AttributeDetails for a database and
1354 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1355 exist for the database.
1357 If the database doesn't exist globally (in TargetInfo) an
1358 AttributeSetInfo must be added (globally).