2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.29 2002-05-07 11:05:19 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", 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", n);
642 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 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",
785 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
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", node_ci);
828 for (i = 0; category[i]; i++)
830 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem,
831 "category", node_ci);
833 data1_mk_tag_data_text (zei->dh, node_cat, "name",
834 category[i], zei->nmem);
836 /* extract *searchable* keys from it. We do this here, because
837 record count, etc. is affected */
839 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
841 /* convert to "SGML" and write it */
843 data1_pr_tree (zei->dh, node_categoryList, stderr);
845 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
846 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
847 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
848 drec->size[recInfo_storeData] = sgml_len;
850 rec_put (zei->records, &drec);
853 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
854 zebAttributeDetails zad,
855 const char *databaseName,
861 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
862 struct zebSUInfoB *zsui;
870 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
873 drec = createRecord (zei->records, &zad->sysno);
874 assert (zad->data1_tree);
875 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree->child,
877 zebraExplain_updateCommonInfo (zei, node_adinfo);
879 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
880 databaseName, zei->nmem);
882 /* extract *searchable* keys from it. We do this here, because
883 record count, etc. is affected */
885 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
887 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
888 "attributesBySet", node_adinfo);
892 data1_node *node_asd;
893 data1_attset *attset;
894 int set_ordinal = -1;
895 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
897 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
898 && zsui->info.set > set_min)
899 set_ordinal = zsui->info.set;
903 set_min = set_ordinal;
904 node_asd = data1_mk_tag (zei->dh, zei->nmem,
905 "attributeSetDetails", node_attributesBySet);
907 attset = data1_attset_search_id (zei->dh, set_ordinal);
910 zebraExplain_loadAttsets (zei->dh, zei->res);
911 attset = data1_attset_search_id (zei->dh, set_ordinal);
918 oe.proto = PROTO_Z3950;
919 oe.oclass = CLASS_ATTSET;
920 oe.value = (enum oid_value) set_ordinal;
922 if (oid_ent_to_oid (&oe, oid))
924 data1_node *node_abt, *node_atd, *node_atvs;
925 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
928 node_abt = data1_mk_tag (zei->dh, zei->nmem,
929 "attributesByType", node_asd);
930 node_atd = data1_mk_tag (zei->dh, zei->nmem,
931 "attributeTypeDetails", node_abt);
932 data1_mk_tag_data_int (zei->dh, node_atd,
933 "type", 1, zei->nmem);
934 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
935 "attributeValues", node_atd);
936 writeAttributeValueDetails (zei, zad, node_atvs, attset);
940 /* zebra info (private) */
941 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
942 "zebraInfo", node_adinfo);
943 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
944 "attrlist", node_zebra);
945 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
947 struct oident oident;
949 data1_node *node_attr;
951 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", node_list);
953 oident.proto = PROTO_Z3950;
954 oident.oclass = CLASS_ATTSET;
955 oident.value = (enum oid_value) zsui->info.set;
956 oid_ent_to_oid (&oident, oid);
958 data1_mk_tag_data_text (zei->dh, node_attr, "set",
959 oident.desc, zei->nmem);
960 data1_mk_tag_data_int (zei->dh, node_attr, "use",
961 zsui->info.use, zei->nmem);
962 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
963 zsui->info.ordinal, zei->nmem);
965 /* convert to "SGML" and write it */
967 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
969 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
971 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
972 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
973 drec->size[recInfo_storeData] = sgml_len;
975 rec_put (zei->records, &drec);
978 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
979 struct zebDatabaseInfoB *zdi,
985 data1_node *node_dbinfo, *node_count, *node_zebra;
992 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
994 drec = createRecord (zei->records, &zdi->sysno);
995 assert (zdi->data1_database);
996 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database->child,
999 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1000 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1002 /* extract *searchable* keys from it. We do this here, because
1003 record count, etc. is affected */
1005 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1007 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1008 "recordCount", node_dbinfo);
1009 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1010 zdi->recordCount, zei->nmem);
1012 /* zebra info (private) */
1013 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1014 "zebraInfo", node_dbinfo);
1015 data1_mk_tag_data_int (zei->dh, node_zebra,
1016 "recordBytes", zdi->recordBytes, zei->nmem);
1017 /* convert to "SGML" and write it */
1019 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1021 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1023 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1024 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1025 drec->size[recInfo_storeData] = sgml_len;
1027 rec_put (zei->records, &drec);
1030 static void writeAttributeValues (ZebraExplainInfo zei,
1031 data1_node *node_values,
1032 data1_attset *attset)
1035 data1_attset_child *c;
1040 for (c = attset->children; c; c = c->next)
1041 writeAttributeValues (zei, node_values, c->child);
1042 for (atts = attset->atts; atts; atts = atts->next)
1044 data1_node *node_value;
1046 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1048 data1_mk_tag_data_text (zei->dh, node_value, "name",
1049 atts->name, zei->nmem);
1050 node_value = data1_mk_tag (zei->dh, zei->nmem, "value", node_value);
1051 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1052 atts->value, zei->nmem);
1057 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1064 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1065 data1_node *node_values;
1066 struct oident *entp;
1067 struct data1_attset *attset = NULL;
1069 if ((entp = oid_getentbyoid (o->oid)))
1070 attset = data1_attset_search_id (zei->dh, entp->value);
1073 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1074 attset ? attset->name : "<unknown>");
1077 drec = createRecord (zei->records, &o->sysno);
1079 data1_read_sgml (zei->dh, zei->nmem,
1080 "<explain><attributeSetInfo>AttributeSetInfo\n"
1083 node_attinfo = data1_search_tag (zei->dh, node_root->child,
1084 "attributeSetInfo");
1086 zebraExplain_initCommonInfo (zei, node_attinfo);
1087 zebraExplain_updateCommonInfo (zei, node_attinfo);
1089 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1090 "oid", o->oid, zei->nmem);
1091 if (attset && attset->name)
1092 data1_mk_tag_data_text (zei->dh, node_attinfo,
1093 "name", attset->name, zei->nmem);
1095 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1096 "attributes", node_attinfo);
1097 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1098 "attributeType", node_attributes);
1099 data1_mk_tag_data_text (zei->dh, node_atttype,
1100 "name", "Use", zei->nmem);
1101 data1_mk_tag_data_text (zei->dh, node_atttype,
1102 "description", "Use Attribute", zei->nmem);
1103 data1_mk_tag_data_int (zei->dh, node_atttype,
1104 "type", 1, zei->nmem);
1105 node_values = data1_mk_tag (zei->dh, zei->nmem,
1106 "attributeValues", node_atttype);
1108 writeAttributeValues (zei, node_values, attset);
1110 /* extract *searchable* keys from it. We do this here, because
1111 record count, etc. is affected */
1113 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1114 /* convert to "SGML" and write it */
1116 data1_pr_tree (zei->dh, node_root, stderr);
1118 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1119 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1120 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1121 drec->size[recInfo_storeData] = sgml_len;
1123 rec_put (zei->records, &drec);
1126 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1128 struct zebDatabaseInfoB *zdi;
1129 data1_node *node_tgtinfo, *node_list, *node_zebra;
1138 trec = rec_get (zei->records, 1);
1139 xfree (trec->info[recInfo_storeData]);
1141 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target->child,
1143 assert (node_tgtinfo);
1145 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1146 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1148 /* convert to "SGML" and write it */
1150 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1152 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1153 "zebraInfo", node_tgtinfo);
1154 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1155 ZEBRAVER, zei->nmem);
1156 node_list = data1_mk_tag (zei->dh, zei->nmem,
1157 "databaseList", node_zebra);
1158 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1160 data1_node *node_db;
1161 node_db = data1_mk_tag (zei->dh, zei->nmem,
1162 "database", node_list);
1163 data1_mk_tag_data_text (zei->dh, node_db, "name",
1164 zdi->databaseName, zei->nmem);
1165 data1_mk_tag_data_int (zei->dh, node_db, "id",
1166 zdi->sysno, zei->nmem);
1167 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1168 zdi->attributeDetails->sysno, zei->nmem);
1170 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1171 zei->ordinalSU, zei->nmem);
1173 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1174 zei->runNumber, zei->nmem);
1177 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1179 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1181 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1182 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1183 trec->size[recInfo_storeData] = sgml_len;
1185 rec_put (zei->records, &trec);
1188 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1190 struct zebSUInfoB *zsui;
1192 assert (zei->curDatabaseInfo);
1193 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1194 zsui; zsui=zsui->next)
1195 if (zsui->info.use == use && zsui->info.set == set)
1196 return zsui->info.ordinal;
1200 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1201 const char **db, int *set, int *use)
1203 struct zebDatabaseInfoB *zdb;
1204 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1206 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1207 for ( ;zsui; zsui = zsui->next)
1208 if (zsui->info.ordinal == ord)
1210 *db = zdb->databaseName;
1211 *set = zsui->info.set;
1212 *use = zsui->info.use;
1219 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1220 zebAccessObject *op,
1225 for (ao = *op; ao; ao = ao->next)
1226 if (!oid_oidcmp (oid, ao->oid))
1230 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1233 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1240 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1245 oe.proto = PROTO_Z3950;
1246 oe.oclass = CLASS_ATTSET;
1247 oe.value = (enum oid_value) set;
1249 if (oid_ent_to_oid (&oe, oid))
1251 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1252 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1253 accessInfo->attributeSetIds, oid);
1257 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1259 struct zebSUInfoB *zsui;
1261 assert (zei->curDatabaseInfo);
1262 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1263 zsui; zsui=zsui->next)
1264 if (zsui->info.use == use && zsui->info.set == set)
1266 zebraExplain_addAttributeSet (zei, set);
1267 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1268 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1269 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1270 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1272 zsui->info.set = set;
1273 zsui->info.use = use;
1274 zsui->info.ordinal = (zei->ordinalSU)++;
1275 return zsui->info.ordinal;
1278 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1280 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1281 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1282 accessInfo->schemas, oid);
1285 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1287 assert (zei->curDatabaseInfo);
1291 zei->curDatabaseInfo->recordBytes += adjust_num;
1292 zei->curDatabaseInfo->dirty = 1;
1296 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1298 assert (zei->curDatabaseInfo);
1302 zei->curDatabaseInfo->recordCount += adjust_num;
1303 zei->curDatabaseInfo->dirty = 1;
1307 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1312 yaz_log (LOG_LOG, "zinfo run number=%d", zei->runNumber+adjust_num);
1314 return zei->runNumber += adjust_num;
1317 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1319 RecordAttr *recordAttr;
1321 if (rec->info[recInfo_attr])
1322 return (RecordAttr *) rec->info[recInfo_attr];
1323 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1324 rec->info[recInfo_attr] = (char *) recordAttr;
1325 rec->size[recInfo_attr] = sizeof(*recordAttr);
1327 recordAttr->recordSize = 0;
1328 recordAttr->recordOffset = 0;
1329 recordAttr->runNumber = zei->runNumber;
1333 static void att_loadset(void *p, const char *n, const char *name)
1335 data1_handle dh = (data1_handle) p;
1336 if (!data1_get_attset (dh, name))
1337 logf (LOG_WARN, "Directive attset failed for %s", name);
1340 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1342 res_trav(res, "attset", dh, att_loadset);
1346 zebraExplain_addSU adds to AttributeDetails for a database and
1347 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1348 exist for the database.
1350 If the database doesn't exist globally (in TargetInfo) an
1351 AttributeSetInfo must be added (globally).