+
+ if (!zad->dirty)
+ return;
+
+ zad->dirty = 0;
+#if ZINFO_DEBUG
+ yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
+ data1_pr_tree(zei->dh, zad->data1_tree, stderr);
+#endif
+
+ drec = createRecord(zei->records, &zad->sysno);
+ if (!drec)
+ return;
+ assert(zad->data1_tree);
+
+ node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
+ "/attributeDetails");
+ zebraExplain_updateCommonInfo(zei, node_adinfo);
+
+ /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
+ node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
+ "zebraInfo", node_adinfo);
+
+ /* extract *searchable* keys from it. We do this here, because
+ record count, etc. is affected */
+ if (key_flush)
+ (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
+ node_list = data1_mk_tag_uni(zei->dh, zei->nmem,
+ "attrlist", node_zebra);
+ for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
+ {
+ data1_node *node_attr;
+ node_attr = data1_mk_tag(zei->dh, zei->nmem, "attr", 0 /* attr */,
+ node_list);
+
+ data1_mk_tag_data_text(zei->dh, node_attr, "type",
+ zsui->info.index_type, zei->nmem);
+ data1_mk_tag_data_text(zei->dh, node_attr, "str",
+ zsui->info.str, zei->nmem);
+ data1_mk_tag_data_int(zei->dh, node_attr, "ordinal",
+ zsui->info.ordinal, zei->nmem);
+
+ data1_mk_tag_data_zint(zei->dh, node_attr, "dococcurrences",
+ zsui->info.doc_occurrences, zei->nmem);
+ data1_mk_tag_data_zint(zei->dh, node_attr, "termoccurrences",
+ zsui->info.term_occurrences, zei->nmem);
+ switch(zsui->info.cat)
+ {
+ case zinfo_index_category_index:
+ data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+ "index", zei->nmem); break;
+ case zinfo_index_category_sort:
+ data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+ "sort", zei->nmem); break;
+ case zinfo_index_category_alwaysmatches:
+ data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+ "alwaysmatches", zei->nmem); break;
+ case zinfo_index_category_anchor:
+ data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+ "anchor", zei->nmem); break;
+ }
+ }
+ /* convert to "SGML" and write it */
+#if ZINFO_DEBUG
+ data1_pr_tree(zei->dh, zad->data1_tree, stderr);
+#endif
+ sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
+ 0, &sgml_len);
+ drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+ memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
+ drec->size[recInfo_storeData] = sgml_len;
+
+ rec_put(zei->records, &drec);
+}
+
+static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
+ struct zebDatabaseInfoB *zdi,
+ int key_flush)
+{
+ char *sgml_buf;
+ int sgml_len;
+ Record drec;
+ data1_node *node_dbinfo, *node_count, *node_zebra;
+
+ if (!zdi->dirty)
+ return;
+
+ zdi->dirty = 0;
+#if ZINFO_DEBUG
+ yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
+#endif
+ drec = createRecord(zei->records, &zdi->sysno);
+ if (!drec)
+ return;
+ assert(zdi->data1_database);
+
+ node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
+ "/databaseInfo");
+
+ assert(node_dbinfo);
+ zebraExplain_updateCommonInfo(zei, node_dbinfo);
+ zebraExplain_updateAccessInfo(zei, node_dbinfo, zdi->accessInfo);
+
+ /* record count */
+ node_count = data1_mk_tag_uni(zei->dh, zei->nmem,
+ "recordCount", node_dbinfo);
+ data1_mk_tag_data_zint(zei->dh, node_count, "recordCountActual",
+ zdi->recordCount, zei->nmem);
+
+ /* zebra info (private) */
+ node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
+ "zebraInfo", node_dbinfo);
+
+ /* extract *searchable* keys from it. We do this here, because
+ record count, etc. is affected */
+ if (key_flush)
+ (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
+ data1_mk_tag_data_zint(zei->dh, node_zebra,
+ "recordBytes", zdi->recordBytes, zei->nmem);
+
+ data1_mk_tag_data_zint(zei->dh, node_zebra,
+ "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
+
+ /* convert to "SGML" and write it */
+#if ZINFO_DEBUG
+ data1_pr_tree(zei->dh, zdi->data1_database, stderr);
+#endif
+ sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
+ 0, &sgml_len);
+ drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+ memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
+ drec->size[recInfo_storeData] = sgml_len;
+
+ rec_put(zei->records, &drec);
+}
+
+static void writeAttributeValues(ZebraExplainInfo zei,
+ data1_node *node_values,
+ data1_attset *attset)
+{
+ data1_att *atts;
+ data1_attset_child *c;
+
+ if (!attset)
+ return;
+
+ for (c = attset->children; c; c = c->next)
+ writeAttributeValues(zei, node_values, c->child);
+ for (atts = attset->atts; atts; atts = atts->next)
+ {
+ data1_node *node_value;
+
+ node_value = data1_mk_tag(zei->dh, zei->nmem, "attributeValue",
+ 0 /* attr */, node_values);
+ data1_mk_tag_data_text(zei->dh, node_value, "name",
+ atts->name, zei->nmem);
+ node_value = data1_mk_tag(zei->dh, zei->nmem, "value",
+ 0 /* attr */, node_value);
+ data1_mk_tag_data_int(zei->dh, node_value, "numeric",
+ atts->value, zei->nmem);
+ }
+}
+
+
+static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
+ zebAccessObject o,
+ int key_flush)
+{
+ char *sgml_buf;
+ int sgml_len;
+ Record drec;
+ data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
+ data1_node *node_values;
+ struct data1_attset *attset = 0;