2 * Copyright (C) 1994-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: zinfo.c,v 1.32 2002-07-11 13:15:57 heikki 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;
294 if ( atoi (res_get_def (res, "notimestamps", "0") )== 0)
297 tm = localtime (&our_time);
298 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
299 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
300 tm->tm_hour, tm->tm_min, tm->tm_sec);
302 sprintf (zei->date, "%04d%02d%02d%02d%02d%02d",
305 zdip = &zei->databaseInfo;
306 trec = rec_get (records, 1); /* get "root" record */
311 zebraExplain_mergeAccessInfo (zei, 0, &zei->accessInfo);
312 if (trec) /* targetInfo already exists ... */
314 data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
316 zei->data1_target = read_sgml_rec (zei->dh, zei->nmem, trec);
318 if (!zei->data1_target || !zei->data1_target->u.root.absyn)
320 if (!zei->data1_target)
323 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
324 nmem_destroy (zei->nmem);
328 data1_pr_tree (zei->dh, zei->data1_target, stderr);
330 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
332 zebraExplain_mergeAccessInfo (zei, node_tgtinfo,
335 node_zebra = data1_search_tag (zei->dh, node_tgtinfo->child,
340 node_list = data1_search_tag (zei->dh, node_zebra->child,
343 np = node_list->child;
345 for (; np; np = np->next)
347 data1_node *node_name = NULL;
348 data1_node *node_id = NULL;
349 data1_node *node_aid = NULL;
351 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "database"))
353 for (np2 = np->child; np2; np2 = np2->next)
355 if (np2->which != DATA1N_tag)
357 if (!strcmp (np2->u.tag.tag, "name"))
358 node_name = np2->child;
359 else if (!strcmp (np2->u.tag.tag, "id"))
360 node_id = np2->child;
361 else if (!strcmp (np2->u.tag.tag, "attributeDetailsId"))
362 node_aid = np2->child;
364 assert (node_id && node_name && node_aid);
366 *zdip = (struct zebDatabaseInfoB *)
367 nmem_malloc (zei->nmem, sizeof(**zdip));
368 (*zdip)->readFlag = 1;
370 (*zdip)->data1_database = NULL;
371 (*zdip)->recordCount = 0;
372 (*zdip)->recordBytes = 0;
373 zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
375 (*zdip)->databaseName = (char *)
376 nmem_malloc (zei->nmem, 1+node_name->u.data.len);
377 memcpy ((*zdip)->databaseName, node_name->u.data.data,
378 node_name->u.data.len);
379 (*zdip)->databaseName[node_name->u.data.len] = '\0';
380 (*zdip)->sysno = atoi_n (node_id->u.data.data,
381 node_id->u.data.len);
382 (*zdip)->attributeDetails = (zebAttributeDetails)
383 nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
384 (*zdip)->attributeDetails->sysno = atoi_n (node_aid->u.data.data,
385 node_aid->u.data.len);
386 (*zdip)->attributeDetails->readFlag = 1;
387 (*zdip)->attributeDetails->dirty = 0;
388 (*zdip)->attributeDetails->SUInfo = NULL;
390 zdip = &(*zdip)->next;
394 np = data1_search_tag (zei->dh, node_zebra->child,
397 assert (np && np->which == DATA1N_data);
398 zei->ordinalSU = atoi_n (np->u.data.data, np->u.data.len);
400 np = data1_search_tag (zei->dh, node_zebra->child,
403 assert (np && np->which == DATA1N_data);
404 zei->runNumber = atoi_n (np->u.data.data, np->u.data.len);
405 yaz_log (LOG_LOG, "READ runnumber = %d", zei->runNumber);
410 else /* create initial targetInfo */
412 data1_node *node_tgtinfo;
421 data1_read_sgml (zei->dh, zei->nmem,
422 "<explain><targetInfo>TargetInfo\n"
424 "<namedResultSets>1</>\n"
425 "<multipleDBSearch>1</>\n"
426 "<nicknames><name>Zebra</></>\n"
428 if (!zei->data1_target)
430 logf (LOG_FATAL, "Explain schema missing. Check profilePath");
431 nmem_destroy (zei->nmem);
434 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
436 assert (node_tgtinfo);
438 zebraExplain_initCommonInfo (zei, node_tgtinfo);
439 zebraExplain_initAccessInfo (zei, node_tgtinfo);
441 /* write now because we want to be sure about the sysno */
442 trec = rec_new (records);
443 trec->info[recInfo_fileType] =
444 rec_strdup ("grs.sgml", &trec->size[recInfo_fileType]);
445 trec->info[recInfo_databaseName] =
446 rec_strdup ("IR-Explain-1", &trec->size[recInfo_databaseName]);
448 sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
449 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
450 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
451 trec->size[recInfo_storeData] = sgml_len;
453 rec_put (records, &trec);
457 zebraExplain_newDatabase (zei, "IR-Explain-1", 0);
459 if (!zei->categoryList->dirty)
461 struct zebraCategoryListInfo *zcl = zei->categoryList;
465 zcl->data1_categoryList =
466 data1_read_sgml (zei->dh, zei->nmem,
467 "<explain><categoryList>CategoryList\n"
470 if (zcl->data1_categoryList)
472 node_cl = data1_search_tag (zei->dh, zcl->data1_categoryList,
475 zebraExplain_initCommonInfo (zei, node_cl);
482 static void zebraExplain_readAttributeDetails (ZebraExplainInfo zei,
483 zebAttributeDetails zad)
486 struct zebSUInfoB **zsuip = &zad->SUInfo;
487 data1_node *node_adinfo, *node_zebra, *node_list, *np;
490 rec = rec_get (zei->records, zad->sysno);
492 zad->data1_tree = read_sgml_rec (zei->dh, zei->nmem, rec);
494 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
495 "/attributeDetails");
496 node_zebra = data1_search_tag (zei->dh, node_adinfo->child,
498 node_list = data1_search_tag (zei->dh, node_zebra->child,
500 for (np = node_list->child; np; np = np->next)
502 data1_node *node_set = NULL;
503 data1_node *node_use = NULL;
504 data1_node *node_ordinal = NULL;
509 if (np->which != DATA1N_tag || strcmp (np->u.tag.tag, "attr"))
511 for (np2 = np->child; np2; np2 = np2->next)
513 if (np2->which != DATA1N_tag || !np2->child ||
514 np2->child->which != DATA1N_data)
516 if (!strcmp (np2->u.tag.tag, "set"))
517 node_set = np2->child;
518 else if (!strcmp (np2->u.tag.tag, "use"))
519 node_use = np2->child;
520 else if (!strcmp (np2->u.tag.tag, "ordinal"))
521 node_ordinal = np2->child;
523 assert (node_set && node_use && node_ordinal);
525 oid_str_len = node_set->u.data.len;
526 if (oid_str_len >= (int) sizeof(oid_str))
527 oid_str_len = sizeof(oid_str)-1;
528 memcpy (oid_str, node_set->u.data.data, oid_str_len);
529 oid_str[oid_str_len] = '\0';
531 *zsuip = (struct zebSUInfoB *)
532 nmem_malloc (zei->nmem, sizeof(**zsuip));
533 (*zsuip)->info.set = oid_getvalbyname (oid_str);
535 (*zsuip)->info.use = atoi_n (node_use->u.data.data,
536 node_use->u.data.len);
537 (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
538 node_ordinal->u.data.len);
539 logf (LOG_DEBUG, "set=%d use=%d ordinal=%d",
540 (*zsuip)->info.set, (*zsuip)->info.use, (*zsuip)->info.ordinal);
541 zsuip = &(*zsuip)->next;
548 static void zebraExplain_readDatabase (ZebraExplainInfo zei,
549 struct zebDatabaseInfoB *zdi)
552 data1_node *node_dbinfo, *node_zebra, *np;
555 rec = rec_get (zei->records, zdi->sysno);
557 zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
559 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
561 assert (node_dbinfo);
562 zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
564 node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
567 && (np = data1_search_tag (zei->dh, node_zebra->child,
569 && np->child && np->child->which == DATA1N_data)
570 zdi->recordBytes = atoi_n (np->child->u.data.data,
571 np->child->u.data.len);
572 if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
574 (np = data1_search_tag (zei->dh, np->child,
575 "recordCountActual")) &&
576 np->child->which == DATA1N_data)
578 zdi->recordCount = atoi_n (np->child->u.data.data,
579 np->child->u.data.len);
585 int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
587 struct zebDatabaseInfoB *zdi;
588 const char *database_n = strrchr (database, '/');
593 database_n = database;
596 if (zei->curDatabaseInfo &&
597 !strcmp (zei->curDatabaseInfo->databaseName, database))
599 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
601 if (!strcmp (zdi->databaseName, database_n))
607 logf (LOG_LOG, "zebraExplain_curDatabase: %s", database);
612 logf (LOG_LOG, "zebraExplain_readDatabase: %s", database);
614 zebraExplain_readDatabase (zei, zdi);
616 if (zdi->attributeDetails->readFlag)
619 logf (LOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
621 zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
623 zei->curDatabaseInfo = zdi;
627 static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
629 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
630 data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
631 data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
632 data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
635 static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
637 data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
639 data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
643 static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
645 data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
646 data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
647 data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
650 static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
651 zebAccessInfo accessInfo)
653 data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
659 data1_pr_tree (zei->dh, n, stdout);
664 if ((p = accessInfo->attributeSetIds))
666 d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
667 for (; p; p = p->next)
668 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
670 if ((p = accessInfo->schemas))
672 d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
673 for (; p; p = p->next)
674 data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
678 int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
679 int explain_database)
681 struct zebDatabaseInfoB *zdi;
682 data1_node *node_dbinfo, *node_adinfo;
683 const char *database_n = strrchr (database, '/');
688 database_n = database;
691 logf (LOG_LOG, "zebraExplain_newDatabase: %s", database);
694 for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
696 if (!strcmp (zdi->databaseName, database_n))
701 /* it's new really. make it */
702 zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
703 zdi->next = zei->databaseInfo;
704 zei->databaseInfo = zdi;
706 zdi->recordCount = 0;
707 zdi->recordBytes = 0;
709 zdi->databaseName = nmem_strdup (zei->nmem, database_n);
711 zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
716 zdi->data1_database =
717 data1_read_sgml (zei->dh, zei->nmem,
718 "<explain><databaseInfo>DatabaseInfo\n"
720 if (!zdi->data1_database)
723 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
725 assert (node_dbinfo);
727 zebraExplain_initCommonInfo (zei, node_dbinfo);
728 zebraExplain_initAccessInfo (zei, node_dbinfo);
730 data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
731 database, zei->nmem);
733 if (explain_database)
734 data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
737 data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
740 data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
744 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
748 zei->curDatabaseInfo = zdi;
750 zdi->attributeDetails = (zebAttributeDetails)
751 nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
752 zdi->attributeDetails->readFlag = 0;
753 zdi->attributeDetails->sysno = 0;
754 zdi->attributeDetails->dirty = 1;
755 zdi->attributeDetails->SUInfo = NULL;
756 zdi->attributeDetails->data1_tree =
757 data1_read_sgml (zei->dh, zei->nmem,
758 "<explain><attributeDetails>AttributeDetails\n"
761 node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
762 "/attributeDetails");
763 assert (node_adinfo);
765 zebraExplain_initCommonInfo (zei, node_adinfo);
770 static void writeAttributeValueDetails (ZebraExplainInfo zei,
771 zebAttributeDetails zad,
772 data1_node *node_atvs, data1_attset *attset)
775 struct zebSUInfoB *zsui;
776 int set_ordinal = attset->reference;
777 data1_attset_child *c;
779 for (c = attset->children; c; c = c->next)
780 writeAttributeValueDetails (zei, zad, node_atvs, c->child);
781 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
783 data1_node *node_attvalue, *node_value;
784 if (set_ordinal != zsui->info.set)
786 node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
787 0 /* attr */, node_atvs);
788 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
789 0 /* attr */, node_attvalue);
790 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
791 zsui->info.use, zei->nmem);
795 static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
796 struct zebraCategoryListInfo *zcl,
803 data1_node *node_ci, *node_categoryList;
805 static char *category[] = {
817 node_categoryList = zcl->data1_categoryList;
820 logf (LOG_LOG, "zebraExplain_writeCategoryList");
823 drec = createRecord (zei->records, &sysno);
825 node_ci = data1_search_tag (zei->dh, node_categoryList,
828 node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
832 for (i = 0; category[i]; i++)
834 data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem, "category",
835 0 /* attr */, node_ci);
837 data1_mk_tag_data_text (zei->dh, node_cat, "name",
838 category[i], zei->nmem);
840 /* extract *searchable* keys from it. We do this here, because
841 record count, etc. is affected */
843 (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
845 /* convert to "SGML" and write it */
847 data1_pr_tree (zei->dh, node_categoryList, stderr);
849 sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
850 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
851 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
852 drec->size[recInfo_storeData] = sgml_len;
854 rec_put (zei->records, &drec);
857 static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
858 zebAttributeDetails zad,
859 const char *databaseName,
865 data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
866 struct zebSUInfoB *zsui;
874 logf (LOG_LOG, "zebraExplain_writeAttributeDetails");
877 drec = createRecord (zei->records, &zad->sysno);
878 assert (zad->data1_tree);
880 node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
881 "/attributeDetails");
882 zebraExplain_updateCommonInfo (zei, node_adinfo);
884 data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
885 databaseName, zei->nmem);
887 /* extract *searchable* keys from it. We do this here, because
888 record count, etc. is affected */
890 (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
892 node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
893 "attributesBySet", node_adinfo);
897 data1_node *node_asd;
898 data1_attset *attset;
899 int set_ordinal = -1;
900 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
902 if ((set_ordinal < 0 || set_ordinal > zsui->info.set)
903 && zsui->info.set > set_min)
904 set_ordinal = zsui->info.set;
908 set_min = set_ordinal;
909 node_asd = data1_mk_tag (zei->dh, zei->nmem,
910 "attributeSetDetails",
911 0 /* attr */, node_attributesBySet);
913 attset = data1_attset_search_id (zei->dh, set_ordinal);
916 zebraExplain_loadAttsets (zei->dh, zei->res);
917 attset = data1_attset_search_id (zei->dh, set_ordinal);
924 oe.proto = PROTO_Z3950;
925 oe.oclass = CLASS_ATTSET;
926 oe.value = (enum oid_value) set_ordinal;
928 if (oid_ent_to_oid (&oe, oid))
930 data1_node *node_abt, *node_atd, *node_atvs;
931 data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
934 node_abt = data1_mk_tag (zei->dh, zei->nmem,
936 0 /*attr */, node_asd);
937 node_atd = data1_mk_tag (zei->dh, zei->nmem,
938 "attributeTypeDetails",
939 0 /* attr */, node_abt);
940 data1_mk_tag_data_int (zei->dh, node_atd,
941 "type", 1, zei->nmem);
942 node_atvs = data1_mk_tag (zei->dh, zei->nmem,
944 0 /* attr */, node_atd);
945 writeAttributeValueDetails (zei, zad, node_atvs, attset);
949 /* zebra info (private) */
950 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
951 "zebraInfo", node_adinfo);
952 node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
953 "attrlist", node_zebra);
954 for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
956 struct oident oident;
958 data1_node *node_attr;
960 node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
963 oident.proto = PROTO_Z3950;
964 oident.oclass = CLASS_ATTSET;
965 oident.value = (enum oid_value) zsui->info.set;
966 oid_ent_to_oid (&oident, oid);
968 data1_mk_tag_data_text (zei->dh, node_attr, "set",
969 oident.desc, zei->nmem);
970 data1_mk_tag_data_int (zei->dh, node_attr, "use",
971 zsui->info.use, zei->nmem);
972 data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
973 zsui->info.ordinal, zei->nmem);
975 /* convert to "SGML" and write it */
977 data1_pr_tree (zei->dh, zad->data1_tree, stderr);
979 sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
981 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
982 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
983 drec->size[recInfo_storeData] = sgml_len;
985 rec_put (zei->records, &drec);
988 static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
989 struct zebDatabaseInfoB *zdi,
995 data1_node *node_dbinfo, *node_count, *node_zebra;
1002 logf (LOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1004 drec = createRecord (zei->records, &zdi->sysno);
1005 assert (zdi->data1_database);
1007 node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
1010 assert (node_dbinfo);
1011 zebraExplain_updateCommonInfo (zei, node_dbinfo);
1012 zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
1014 /* extract *searchable* keys from it. We do this here, because
1015 record count, etc. is affected */
1017 (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1019 node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
1020 "recordCount", node_dbinfo);
1021 data1_mk_tag_data_int (zei->dh, node_count, "recordCountActual",
1022 zdi->recordCount, zei->nmem);
1024 /* zebra info (private) */
1025 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1026 "zebraInfo", node_dbinfo);
1027 data1_mk_tag_data_int (zei->dh, node_zebra,
1028 "recordBytes", zdi->recordBytes, zei->nmem);
1029 /* convert to "SGML" and write it */
1031 data1_pr_tree (zei->dh, zdi->data1_database, stderr);
1033 sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1035 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1036 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1037 drec->size[recInfo_storeData] = sgml_len;
1039 rec_put (zei->records, &drec);
1042 static void writeAttributeValues (ZebraExplainInfo zei,
1043 data1_node *node_values,
1044 data1_attset *attset)
1047 data1_attset_child *c;
1052 for (c = attset->children; c; c = c->next)
1053 writeAttributeValues (zei, node_values, c->child);
1054 for (atts = attset->atts; atts; atts = atts->next)
1056 data1_node *node_value;
1058 node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
1059 0 /* attr */, node_values);
1060 data1_mk_tag_data_text (zei->dh, node_value, "name",
1061 atts->name, zei->nmem);
1062 node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
1063 0 /* attr */, node_value);
1064 data1_mk_tag_data_int (zei->dh, node_value, "numeric",
1065 atts->value, zei->nmem);
1070 static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
1077 data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1078 data1_node *node_values;
1079 struct oident *entp;
1080 struct data1_attset *attset = NULL;
1082 if ((entp = oid_getentbyoid (o->oid)))
1083 attset = data1_attset_search_id (zei->dh, entp->value);
1086 logf (LOG_LOG, "zebraExplain_writeAttributeSet %s",
1087 attset ? attset->name : "<unknown>");
1090 drec = createRecord (zei->records, &o->sysno);
1092 data1_read_sgml (zei->dh, zei->nmem,
1093 "<explain><attributeSetInfo>AttributeSetInfo\n"
1096 node_attinfo = data1_search_tag (zei->dh, node_root,
1097 "/attributeSetInfo");
1099 assert (node_attinfo);
1100 zebraExplain_initCommonInfo (zei, node_attinfo);
1101 zebraExplain_updateCommonInfo (zei, node_attinfo);
1103 data1_mk_tag_data_oid (zei->dh, node_attinfo,
1104 "oid", o->oid, zei->nmem);
1105 if (attset && attset->name)
1106 data1_mk_tag_data_text (zei->dh, node_attinfo,
1107 "name", attset->name, zei->nmem);
1109 node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
1110 "attributes", node_attinfo);
1111 node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
1112 "attributeType", node_attributes);
1113 data1_mk_tag_data_text (zei->dh, node_atttype,
1114 "name", "Use", zei->nmem);
1115 data1_mk_tag_data_text (zei->dh, node_atttype,
1116 "description", "Use Attribute", zei->nmem);
1117 data1_mk_tag_data_int (zei->dh, node_atttype,
1118 "type", 1, zei->nmem);
1119 node_values = data1_mk_tag (zei->dh, zei->nmem,
1120 "attributeValues", 0 /* attr */, node_atttype);
1122 writeAttributeValues (zei, node_values, attset);
1124 /* extract *searchable* keys from it. We do this here, because
1125 record count, etc. is affected */
1127 (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1128 /* convert to "SGML" and write it */
1130 data1_pr_tree (zei->dh, node_root, stderr);
1132 sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1133 drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1134 memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
1135 drec->size[recInfo_storeData] = sgml_len;
1137 rec_put (zei->records, &drec);
1140 static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
1142 struct zebDatabaseInfoB *zdi;
1143 data1_node *node_tgtinfo, *node_list, *node_zebra;
1152 trec = rec_get (zei->records, 1);
1153 xfree (trec->info[recInfo_storeData]);
1155 node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
1157 assert (node_tgtinfo);
1159 zebraExplain_updateCommonInfo (zei, node_tgtinfo);
1160 zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
1162 /* convert to "SGML" and write it */
1164 (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1166 node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
1167 "zebraInfo", node_tgtinfo);
1168 data1_mk_tag_data_text (zei->dh, node_zebra, "version",
1169 ZEBRAVER, zei->nmem);
1170 node_list = data1_mk_tag (zei->dh, zei->nmem,
1171 "databaseList", 0 /* attr */, node_zebra);
1172 for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1174 data1_node *node_db;
1175 node_db = data1_mk_tag (zei->dh, zei->nmem,
1176 "database", 0 /* attr */, node_list);
1177 data1_mk_tag_data_text (zei->dh, node_db, "name",
1178 zdi->databaseName, zei->nmem);
1179 data1_mk_tag_data_int (zei->dh, node_db, "id",
1180 zdi->sysno, zei->nmem);
1181 data1_mk_tag_data_int (zei->dh, node_db, "attributeDetailsId",
1182 zdi->attributeDetails->sysno, zei->nmem);
1184 data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
1185 zei->ordinalSU, zei->nmem);
1187 data1_mk_tag_data_int (zei->dh, node_zebra, "runNumber",
1188 zei->runNumber, zei->nmem);
1191 data1_pr_tree (zei->dh, zei->data1_target, stderr);
1193 sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1195 trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
1196 memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
1197 trec->size[recInfo_storeData] = sgml_len;
1199 rec_put (zei->records, &trec);
1202 int zebraExplain_lookupSU (ZebraExplainInfo zei, int set, int use)
1204 struct zebSUInfoB *zsui;
1206 assert (zei->curDatabaseInfo);
1207 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1208 zsui; zsui=zsui->next)
1209 if (zsui->info.use == use && zsui->info.set == set)
1210 return zsui->info.ordinal;
1214 int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord,
1215 const char **db, int *set, int *use)
1217 struct zebDatabaseInfoB *zdb;
1218 for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1220 struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1221 for ( ;zsui; zsui = zsui->next)
1222 if (zsui->info.ordinal == ord)
1224 *db = zdb->databaseName;
1225 *set = zsui->info.set;
1226 *use = zsui->info.use;
1233 zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
1234 zebAccessObject *op,
1239 for (ao = *op; ao; ao = ao->next)
1240 if (!oid_oidcmp (oid, ao->oid))
1244 ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
1247 ao->oid = odr_oiddup_nmem (zei->nmem, oid);
1254 void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
1259 oe.proto = PROTO_Z3950;
1260 oe.oclass = CLASS_ATTSET;
1261 oe.value = (enum oid_value) set;
1263 if (oid_ent_to_oid (&oe, oid))
1265 zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
1266 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1267 accessInfo->attributeSetIds, oid);
1271 int zebraExplain_addSU (ZebraExplainInfo zei, int set, int use)
1273 struct zebSUInfoB *zsui;
1275 assert (zei->curDatabaseInfo);
1276 for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
1277 zsui; zsui=zsui->next)
1278 if (zsui->info.use == use && zsui->info.set == set)
1280 zebraExplain_addAttributeSet (zei, set);
1281 zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
1282 zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1283 zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1284 zei->curDatabaseInfo->attributeDetails->dirty = 1;
1286 zsui->info.set = set;
1287 zsui->info.use = use;
1288 zsui->info.ordinal = (zei->ordinalSU)++;
1289 return zsui->info.ordinal;
1292 void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
1294 zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
1295 zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
1296 accessInfo->schemas, oid);
1299 void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
1301 assert (zei->curDatabaseInfo);
1305 zei->curDatabaseInfo->recordBytes += adjust_num;
1306 zei->curDatabaseInfo->dirty = 1;
1310 void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
1312 assert (zei->curDatabaseInfo);
1316 zei->curDatabaseInfo->recordCount += adjust_num;
1317 zei->curDatabaseInfo->dirty = 1;
1321 int zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
1326 yaz_log (LOG_LOG, "zinfo run number=%d", zei->runNumber+adjust_num);
1328 return zei->runNumber += adjust_num;
1331 RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
1333 RecordAttr *recordAttr;
1335 if (rec->info[recInfo_attr])
1336 return (RecordAttr *) rec->info[recInfo_attr];
1337 recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
1338 rec->info[recInfo_attr] = (char *) recordAttr;
1339 rec->size[recInfo_attr] = sizeof(*recordAttr);
1341 recordAttr->recordSize = 0;
1342 recordAttr->recordOffset = 0;
1343 recordAttr->runNumber = zei->runNumber;
1347 static void att_loadset(void *p, const char *n, const char *name)
1349 data1_handle dh = (data1_handle) p;
1350 if (!data1_get_attset (dh, name))
1351 logf (LOG_WARN, "Directive attset failed for %s", name);
1354 void zebraExplain_loadAttsets (data1_handle dh, Res res)
1356 res_trav(res, "attset", dh, att_loadset);
1360 zebraExplain_addSU adds to AttributeDetails for a database and
1361 adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1362 exist for the database.
1364 If the database doesn't exist globally (in TargetInfo) an
1365 AttributeSetInfo must be added (globally).