2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.31 2002-07-03 10: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,
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,
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 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
470 zebraExplain_initCommonInfo (zei, node_cl);
477 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
478 zebAttributeDetails zad)
481 struct zebSUInfoB **zsuip = &zad->SUInfo;
482 data1_node *node_adinfo, *node_zebra, *node_list, *np;
485 rec = rec_get (zei->records, zad->sysno);
487 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
489 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
490 "/attributeDetails");
491 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
493 node_list = data1_search_tag (zei->dh, node_zebra->child,
495 for (np = node_list->child; np; np = np->next)
497 data1_node *node_set = NULL;
498 data1_node *node_use = NULL;
499 data1_node *node_ordinal = NULL;
504 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
506 for (np2 = np->child; np2; np2 = np2->next)
508 if (np2->which != DATA1N_tag || !np2->child ||
509 np2->child->which != DATA1N_data)
511 if (!strcmp (np2->u.tag.tag, "set"))
512 node_set = np2->child;
513 else if (!strcmp (np2->u.tag.tag, "use"))
514 node_use = np2->child;
515 else if (!strcmp (np2->u.tag.tag, "ordinal"))
516 node_ordinal = np2->child;
518 assert (node_set && node_use && node_ordinal);
520 oid_str_len = node_set->u.data.len;
521 if (oid_str_len >= (int) sizeof(oid_str))
522 oid_str_len = sizeof(oid_str)-1;
523 memcpy (oid_str, node_set->u.data.data, oid_str_len);
524 oid_str[oid_str_len] = '\0';
526 *zsuip = (struct zebSUInfoB *)
527 nmem_malloc (zei->nmem, sizeof(**zsuip));
528 (*zsuip)->info.set = oid_getvalbyname (oid_str);
530 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
531 node_use->u.data.len);
532 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
533 node_ordinal->u.data.len);
534 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
535 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
536 zsuip = &(*zsuip)->next;
543 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
544 struct zebDatabaseInfoB *zdi)
547 data1_node *node_dbinfo, *node_zebra, *np;
550 rec = rec_get (zei->records, zdi->sysno);
552 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
554 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
556 assert (node_dbinfo);
557 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
559 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
562 && (np = data1_search_tag (zei->dh, node_zebra->child,
564 && np->child && np->child->which == DATA1N_data)
565 zdi->recordBytes = atoi_n (np->child->u.data.data,
566 np->child->u.data.len);
567 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
569 (np = data1_search_tag (zei->dh, np->child,
570 "recordCountActual")) &&
571 np->child->which == DATA1N_data)
573 zdi->recordCount = atoi_n (np->child->u.data.data,
574 np->child->u.data.len);
580 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
582 struct zebDatabaseInfoB *zdi;
583 const char *database_n = strrchr (database, '/');
588 database_n = database;
591 if (zei->curDatabaseInfo &&
592 !strcmp (zei->curDatabaseInfo->databaseName, database))
594 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
596 if (!strcmp (zdi->databaseName, database_n))
602 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
607 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
609 zebraExplain_readDatabase (zei, zdi);
611 if (zdi->attributeDetails->readFlag)
614 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
616 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
618 zei->curDatabaseInfo = zdi;
622 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
624 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
625 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
626 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
627 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
630 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
632 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
634 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
638 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
640 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
641 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
642 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
645 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
646 zebAccessInfo accessInfo)
648 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
654 data1_pr_tree (zei->dh, n, stdout);
659 if ((p = accessInfo->attributeSetIds))
661 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
662 for (; p; p = p->next)
663 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
665 if ((p = accessInfo->schemas))
667 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
668 for (; p; p = p->next)
669 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
673 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
674 int explain_database)
676 struct zebDatabaseInfoB *zdi;
677 data1_node *node_dbinfo, *node_adinfo;
678 const char *database_n = strrchr (database, '/');
683 database_n = database;
686 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
689 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
691 if (!strcmp (zdi->databaseName, database_n))
696 /* it's new really. make it */
697 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
698 zdi->next = zei->databaseInfo;
699 zei->databaseInfo = zdi;
701 zdi->recordCount = 0;
702 zdi->recordBytes = 0;
704 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
706 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
711 zdi->data1_database =
712 data1_read_sgml (zei->dh, zei->nmem,
713 "<explain><databaseInfo>DatabaseInfo\n"
715 if (!zdi->data1_database)
718 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
720 assert (node_dbinfo);
722 zebraExplain_initCommonInfo (zei, node_dbinfo);
723 zebraExplain_initAccessInfo (zei, node_dbinfo);
725 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
726 database, zei->nmem);
728 if (explain_database)
729 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
732 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
735 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
739 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
743 zei->curDatabaseInfo = zdi;
745 zdi->attributeDetails = (zebAttributeDetails)
746 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
747 zdi->attributeDetails->readFlag = 0;
748 zdi->attributeDetails->sysno = 0;
749 zdi->attributeDetails->dirty = 1;
750 zdi->attributeDetails->SUInfo = NULL;
751 zdi->attributeDetails->data1_tree =
752 data1_read_sgml (zei->dh, zei->nmem,
753 "<explain><attributeDetails>AttributeDetails\n"
756 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
757 "/attributeDetails");
758 assert (node_adinfo);
760 zebraExplain_initCommonInfo (zei, node_adinfo);
765 static void writeAttributeValueDetails (ZebraExplainInfo zei,
766 zebAttributeDetails zad,
767 data1_node *node_atvs, data1_attset *attset)
770 struct zebSUInfoB *zsui;
771 int set_ordinal = attset->reference;
772 data1_attset_child *c;
774 for (c = attset->children; c; c = c->next)
775 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
776 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
778 data1_node *node_attvalue, *node_value;
779 if (set_ordinal != zsui->info.set)
781 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
782 0 /* attr */, node_atvs);
783 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
784 0 /* attr */, node_attvalue);
785 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
786 zsui->info.use, zei->nmem);
790 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
791 struct zebraCategoryListInfo *zcl,
798 data1_node *node_ci, *node_categoryList;
800 static char *category[] = {
812 node_categoryList = zcl->data1_categoryList;
815 logf (LOG_LOG, "zebraExplain_writeCategoryList");
818 drec = createRecord (zei->records, &sysno);
820 node_ci = data1_search_tag (zei->dh, node_categoryList,
823 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
827 for (i = 0; category[i]; i++)
829 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
830 0 /* attr */, node_ci);
832 data1_mk_tag_data_text (zei->dh, node_cat, "name",
833 category[i], zei->nmem);
835 /* extract *searchable* keys from it. We do this here, because
836 record count, etc. is affected */
838 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
840 /* convert to "SGML" and write it */
842 data1_pr_tree (zei->dh, node_categoryList, stderr);
844 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
845 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
846 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
847 drec->size[recInfo_storeData] = sgml_len;
849 rec_put (zei->records, &drec);
852 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
853 zebAttributeDetails zad,
854 const char *databaseName,
860 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
861 struct zebSUInfoB *zsui;
869 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
872 drec = createRecord (zei->records, &zad->sysno);
873 assert (zad->data1_tree);
875 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
876 "/attributeDetails");
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",
906 0 /* attr */, node_attributesBySet);
908 attset = data1_attset_search_id (zei->dh, set_ordinal);
911 zebraExplain_loadAttsets (zei->dh, zei->res);
912 attset = data1_attset_search_id (zei->dh, set_ordinal);
919 oe.proto = PROTO_Z3950;
920 oe.oclass = CLASS_ATTSET;
921 oe.value = (enum oid_value) set_ordinal;
923 if (oid_ent_to_oid (&oe, oid))
925 data1_node *node_abt, *node_atd, *node_atvs;
926 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
929 node_abt = data1_mk_tag (zei->dh, zei->nmem,
931 0 /*attr */, node_asd);
932 node_atd = data1_mk_tag (zei->dh, zei->nmem,
933 "attributeTypeDetails",
934 0 /* attr */, node_abt);
935 data1_mk_tag_data_int (zei->dh, node_atd,
936 "type", 1, zei->nmem);
937 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
939 0 /* attr */, node_atd);
940 writeAttributeValueDetails (zei, zad, node_atvs, attset);
944 /* zebra info (private) */
945 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
946 "zebraInfo", node_adinfo);
947 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
948 "attrlist", node_zebra);
949 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
951 struct oident oident;
953 data1_node *node_attr;
955 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
958 oident.proto = PROTO_Z3950;
959 oident.oclass = CLASS_ATTSET;
960 oident.value = (enum oid_value) zsui->info.set;
961 oid_ent_to_oid (&oident, oid);
963 data1_mk_tag_data_text (zei->dh, node_attr, "set",
964 oident.desc, zei->nmem);
965 data1_mk_tag_data_int (zei->dh, node_attr, "use",
966 zsui->info.use, zei->nmem);
967 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
968 zsui->info.ordinal, zei->nmem);
970 /* convert to "SGML" and write it */
972 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
974 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
976 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
977 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
978 drec->size[recInfo_storeData] = sgml_len;
980 rec_put (zei->records, &drec);
983 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
984 struct zebDatabaseInfoB *zdi,
990 data1_node *node_dbinfo, *node_count, *node_zebra;
997 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
999 drec = createRecord (zei->records, &zdi->sysno);
1000 assert (zdi->data1_database);
1002 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1005 assert (node_dbinfo);
1006 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1007 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1009 /* extract *searchable* keys from it. We do this here, because
1010 record count, etc. is affected */
1012 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1014 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1015 "recordCount", node_dbinfo);
1016 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1017 zdi->recordCount, zei->nmem);
1019 /* zebra info (private) */
1020 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1021 "zebraInfo", node_dbinfo);
1022 data1_mk_tag_data_int (zei->dh, node_zebra,
1023 "recordBytes", zdi->recordBytes, zei->nmem);
1024 /* convert to "SGML" and write it */
1026 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1028 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1030 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1031 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1032 drec->size[recInfo_storeData] = sgml_len;
1034 rec_put (zei->records, &drec);
1037 static void writeAttributeValues (ZebraExplainInfo zei,
1038 data1_node *node_values,
1039 data1_attset *attset)
1042 data1_attset_child *c;
1047 for (c = attset->children; c; c = c->next)
1048 writeAttributeValues (zei, node_values, c->child);
1049 for (atts = attset->atts; atts; atts = atts->next)
1051 data1_node *node_value;
1053 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1054 0 /* attr */, node_values);
1055 data1_mk_tag_data_text (zei->dh, node_value, "name",
1056 atts->name, zei->nmem);
1057 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1058 0 /* attr */, node_value);
1059 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1060 atts->value, zei->nmem);
1065 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1072 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1073 data1_node *node_values;
1074 struct oident *entp;
1075 struct data1_attset *attset = NULL;
1077 if ((entp = oid_getentbyoid (o->oid)))
1078 attset = data1_attset_search_id (zei->dh, entp->value);
1081 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1082 attset ? attset->name : "<unknown>");
1085 drec = createRecord (zei->records, &o->sysno);
1087 data1_read_sgml (zei->dh, zei->nmem,
1088 "<explain><attributeSetInfo>AttributeSetInfo\n"
1091 node_attinfo = data1_search_tag (zei->dh, node_root,
1092 "/attributeSetInfo");
1094 assert (node_attinfo);
1095 zebraExplain_initCommonInfo (zei, node_attinfo);
1096 zebraExplain_updateCommonInfo (zei, node_attinfo);
1098 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1099 "oid", o->oid, zei->nmem);
1100 if (attset && attset->name)
1101 data1_mk_tag_data_text (zei->dh, node_attinfo,
1102 "name", attset->name, zei->nmem);
1104 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1105 "attributes", node_attinfo);
1106 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1107 "attributeType", node_attributes);
1108 data1_mk_tag_data_text (zei->dh, node_atttype,
1109 "name", "Use", zei->nmem);
1110 data1_mk_tag_data_text (zei->dh, node_atttype,
1111 "description", "Use Attribute", zei->nmem);
1112 data1_mk_tag_data_int (zei->dh, node_atttype,
1113 "type", 1, zei->nmem);
1114 node_values = data1_mk_tag (zei->dh, zei->nmem,
1115 "attributeValues", 0 /* attr */, node_atttype);
1117 writeAttributeValues (zei, node_values, attset);
1119 /* extract *searchable* keys from it. We do this here, because
1120 record count, etc. is affected */
1122 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1123 /* convert to "SGML" and write it */
1125 data1_pr_tree (zei->dh, node_root, stderr);
1127 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1128 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1129 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1130 drec->size[recInfo_storeData] = sgml_len;
1132 rec_put (zei->records, &drec);
1135 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1137 struct zebDatabaseInfoB *zdi;
1138 data1_node *node_tgtinfo, *node_list, *node_zebra;
1147 trec = rec_get (zei->records, 1);
1148 xfree (trec->info[recInfo_storeData]);
1150 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1152 assert (node_tgtinfo);
1154 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1155 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1157 /* convert to "SGML" and write it */
1159 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1161 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1162 "zebraInfo", node_tgtinfo);
1163 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1164 ZEBRAVER, zei->nmem);
1165 node_list = data1_mk_tag (zei->dh, zei->nmem,
1166 "databaseList", 0 /* attr */, node_zebra);
1167 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1169 data1_node *node_db;
1170 node_db = data1_mk_tag (zei->dh, zei->nmem,
1171 "database", 0 /* attr */, node_list);
1172 data1_mk_tag_data_text (zei->dh, node_db, "name",
1173 zdi->databaseName, zei->nmem);
1174 data1_mk_tag_data_int (zei->dh, node_db, "id",
1175 zdi->sysno, zei->nmem);
1176 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1177 zdi->attributeDetails->sysno, zei->nmem);
1179 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1180 zei->ordinalSU, zei->nmem);
1182 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1183 zei->runNumber, zei->nmem);
1186 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1188 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1190 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1191 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1192 trec->size[recInfo_storeData] = sgml_len;
1194 rec_put (zei->records, &trec);
1197 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1199 struct zebSUInfoB *zsui;
1201 assert (zei->curDatabaseInfo);
1202 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1203 zsui; zsui=zsui->next)
1204 if (zsui->info.use == use && zsui->info.set == set)
1205 return zsui->info.ordinal;
1209 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1210 const char **db, int *set, int *use)
1212 struct zebDatabaseInfoB *zdb;
1213 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1215 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1216 for ( ;zsui; zsui = zsui->next)
1217 if (zsui->info.ordinal == ord)
1219 *db = zdb->databaseName;
1220 *set = zsui->info.set;
1221 *use = zsui->info.use;
1228 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1229 zebAccessObject *op,
1234 for (ao = *op; ao; ao = ao->next)
1235 if (!oid_oidcmp (oid, ao->oid))
1239 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1242 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1249 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1254 oe.proto = PROTO_Z3950;
1255 oe.oclass = CLASS_ATTSET;
1256 oe.value = (enum oid_value) set;
1258 if (oid_ent_to_oid (&oe, oid))
1260 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1261 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1262 accessInfo->attributeSetIds, oid);
1266 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1268 struct zebSUInfoB *zsui;
1270 assert (zei->curDatabaseInfo);
1271 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1272 zsui; zsui=zsui->next)
1273 if (zsui->info.use == use && zsui->info.set == set)
1275 zebraExplain_addAttributeSet (zei, set);
1276 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1277 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1278 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1279 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1281 zsui->info.set = set;
1282 zsui->info.use = use;
1283 zsui->info.ordinal = (zei->ordinalSU)++;
1284 return zsui->info.ordinal;
1287 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1289 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1290 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1291 accessInfo->schemas, oid);
1294 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1296 assert (zei->curDatabaseInfo);
1300 zei->curDatabaseInfo->recordBytes += adjust_num;
1301 zei->curDatabaseInfo->dirty = 1;
1305 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1307 assert (zei->curDatabaseInfo);
1311 zei->curDatabaseInfo->recordCount += adjust_num;
1312 zei->curDatabaseInfo->dirty = 1;
1316 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1321 yaz_log (LOG_LOG, "zinfo run number=%d", zei->runNumber+adjust_num);
1323 return zei->runNumber += adjust_num;
1326 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1328 RecordAttr *recordAttr;
1330 if (rec->info[recInfo_attr])
1331 return (RecordAttr *) rec->info[recInfo_attr];
1332 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1333 rec->info[recInfo_attr] = (char *) recordAttr;
1334 rec->size[recInfo_attr] = sizeof(*recordAttr);
1336 recordAttr->recordSize = 0;
1337 recordAttr->recordOffset = 0;
1338 recordAttr->runNumber = zei->runNumber;
1342 static void att_loadset(void *p, const char *n, const char *name)
1344 data1_handle dh = (data1_handle) p;
1345 if (!data1_get_attset (dh, name))
1346 logf (LOG_WARN, "Directive attset failed for %s", name);
1349 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1351 res_trav(res, "attset", dh, att_loadset);
1355 zebraExplain_addSU adds to AttributeDetails for a database and
1356 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1357 exist for the database.
1359 If the database doesn't exist globally (in TargetInfo) an
1360 AttributeSetInfo must be added (globally).