IDZEBRA  2.1.2
zinfo.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) Index Data
3 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
18 */
19 
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <sys/types.h>
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 
29 #include <idzebra/version.h>
30 #include "zinfo.h"
31 
32 #define ZINFO_DEBUG 0
33 
34 struct zebSUInfo {
35  char *index_type;
37  char *str;
38  int ordinal;
41 };
42 
43 struct zebSUInfoB {
44  struct zebSUInfo info;
45  struct zebSUInfoB *next;
46 };
47 
50  void *handle;
52  Odr_oid *oid;
53  zebAccessObject next;
54 };
55 
56 typedef struct zebAccessInfoB *zebAccessInfo;
58  zebAccessObject attributeSetIds;
59  zebAccessObject schemas;
60 };
61 
62 typedef struct {
63  struct zebSUInfoB *SUInfo;
65  int dirty;
66  int readFlag;
69 
73  char *databaseName;
75  zint recordCount; /* records in db */
76  zint recordBytes; /* size of records */
77  zint sysno; /* sysno of database info */
78  int readFlag; /* 1: read is needed when referenced; 0 if not */
79  int dirty; /* 1: database is dirty: write is needed */
81  zebAccessInfo accessInfo;
82 };
83 
85  char *name;
86  int ordinal;
88 };
89 
91  int dirty;
94 };
95 
97  int ordinalSU;
100  int dirty;
106  NMEM nmem;
111  zebAccessInfo accessInfo;
112  char date[15]; /* YYYY MMDD HH MM SS */
115 };
116 
119 
120 static data1_node *read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
121 {
122  return data1_read_sgml(dh, nmem, rec->info[recInfo_storeData]);
123 }
124 
126  struct zebDatabaseInfoB *zdi,
127  int key_flush);
130  const char *databaseName,
131  int key_flush);
132 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush);
134  zebAccessObject o,
135  int key_flush);
137  struct zebraCategoryListInfo *zcl,
138  int key_flush);
139 
140 
142 {
143  Record rec;
144  if (*sysno)
145  {
146  rec = rec_get(records, *sysno);
147  if (!rec)
148  return 0;
149  xfree(rec->info[recInfo_storeData]);
150  }
151  else
152  {
153  rec = rec_new(records);
154  if (!rec)
155  return 0;
156  *sysno = rec->sysno;
157 
158  rec->info[recInfo_fileType] =
159  rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
160  rec->info[recInfo_databaseName] =
161  rec_strdup("IR-Explain-1",
162  &rec->size[recInfo_databaseName]);
163  }
164  return rec;
165 }
166 
167 void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
168 {
169  if (!zei)
170  return;
171  zei->updateHandle = handle;
172  if (zei->write_flag)
173  {
174  struct zebDatabaseInfoB *zdi;
175  zebAccessObject o;
176 
177  /* write each database info record */
178  for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
179  {
180  zebraExplain_writeDatabase(zei, zdi, 1);
182  zdi->databaseName, 1);
183  }
184  zebraExplain_writeTarget(zei, 1);
186  zei->categoryList,
187  1);
188  assert(zei->accessInfo);
189  for (o = zei->accessInfo->attributeSetIds; o; o = o->next)
190  if (!o->sysno)
192  for (o = zei->accessInfo->schemas; o; o = o->next)
193  if (!o->sysno)
194  {
195 /* zebraExplain_writeSchema(zei, o, 1); */
196  }
197 
198  for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
199  {
200  zebraExplain_writeDatabase(zei, zdi, 0);
202  zdi->databaseName, 0);
203  }
204  zebraExplain_writeTarget(zei, 0);
205  }
206 }
207 
209 {
210 #if ZINFO_DEBUG
211  yaz_log(YLOG_LOG, "zebraExplain_close");
212 #endif
213  if (!zei)
214  return;
215  zebraExplain_flush(zei, zei->updateHandle);
216  nmem_destroy(zei->nmem);
217 }
218 
220  zebAccessObject *op)
221 {
222  data1_node *np;
223 
224  for (np = n->child; np; np = np->next)
225  {
226  char str[64];
227  int len;
228  Odr_oid *oid;
229  zebAccessObject ao;
230 
231  if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "oid"))
232  continue;
233  len = np->child->u.data.len;
234  if (len > 63)
235  len = 63;
236  memcpy(str, np->child->u.data.data, len);
237  str[len] = '\0';
238 
239  oid = odr_getoidbystr_nmem(zei->nmem, str);
240 
241  for (ao = *op; ao; ao = ao->next)
242  if (!oid_oidcmp(oid, ao->oid))
243  {
244  ao->sysno = 1;
245  break;
246  }
247  if (!ao)
248  {
249  ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
250  ao->handle = 0;
251  ao->sysno = 1;
252  ao->oid = oid;
253  ao->next = *op;
254  *op = ao;
255  }
256  }
257 }
258 
260  zebAccessInfo *accessInfo)
261 {
262  data1_node *np;
263 
264  if (!n)
265  {
266  *accessInfo = (zebAccessInfo)
267  nmem_malloc(zei->nmem, sizeof(**accessInfo));
268  (*accessInfo)->attributeSetIds = 0;
269  (*accessInfo)->schemas = 0;
270  }
271  else
272  {
273  if (!(n = data1_search_tag(zei->dh, n->child, "accessInfo")))
274  return;
275  if ((np = data1_search_tag(zei->dh, n->child, "attributeSetIds")))
276  zebraExplain_mergeOids(zei, np,
277  &(*accessInfo)->attributeSetIds);
278  if ((np = data1_search_tag(zei->dh, n->child, "schemas")))
279  zebraExplain_mergeOids(zei, np,
280  &(*accessInfo)->schemas);
281  }
282 }
283 
284 /* Explain structure
285  root record
286  of type targetInfo
287  and has sysno = 1
288 
289  databaseList (list of databases)
290 */
291 /*
292 Example root:
293 explain:
294  targetInfo: TargetInfo
295  name: Zebra
296  namedResultSets: 1
297  multipleDbSearch: 1
298  nicknames:
299  name: Zebra
300  commonInfo:
301  dateAdded: 20030630190601
302  dateChanged: 20030630190601
303  languageCode: EN
304  accessinfo:
305  unitSystems:
306  string: ISO
307  attributeSetIds:
308  oid: 1.2.840.10003.3.2
309  oid: 1.2.840.10003.3.5
310  oid: 1.2.840.10003.3.1
311  schemas:
312  oid: 1.2.840.10003.13.1000.81.2
313  oid: 1.2.840.10003.13.2
314  zebraInfo:
315  version: 1.3.12
316  databaseList:
317  database:
318  name: Default
319  id: 50
320  attributeDetailsId: 51
321  database:
322  name: IR-Explain-1
323  id: 52
324  attributeDetailsId: 53
325  ordinalSU: 38
326  runNumber: 1
327 nextResultSetPosition = 2
328 */
329 
331  Records records, data1_handle dh,
332  Res res,
333  int writeFlag,
334  void *updateHandle,
335  ZebraExplainUpdateFunc *updateFunc)
336 {
337  Record trec;
338  ZebraExplainInfo zei;
339  struct zebDatabaseInfoB **zdip;
340  time_t our_time;
341  struct tm *tm;
342  NMEM nmem = nmem_create();
343 
344 #if ZINFO_DEBUG
345  yaz_log(YLOG_LOG, "zebraExplain_open wr=%d", writeFlag);
346 #endif
347  zei = (ZebraExplainInfo) nmem_malloc(nmem, sizeof(*zei));
348  zei->databaseInfo = 0;
349  zei->write_flag = writeFlag;
350  zei->updateHandle = updateHandle;
351  zei->updateFunc = updateFunc;
352  zei->dirty = 0;
353  zei->ordinalDatabase = 1;
354  zei->curDatabaseInfo = 0;
355  zei->records = records;
356  zei->nmem = nmem;
357  zei->dh = dh;
358 
360 
361  zei->attsets = 0;
362  zei->res = res;
363  zei->categoryList = (struct zebraCategoryListInfo *)
364  nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
365  zei->categoryList->sysno = 0;
366  zei->categoryList->dirty = 0;
368 
369  if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
370  {
371  time(&our_time);
372  tm = localtime(&our_time);
373  sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
374  tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
375  tm->tm_hour, tm->tm_min, tm->tm_sec);
376  } else {
377  sprintf(zei->date, "%04d%02d%02d%02d%02d%02d",
378  0, 0, 0, 0, 0, 0);
379  }
380  zdip = &zei->databaseInfo;
381  trec = rec_get_root(records); /* get "root" record */
382 
383  zei->ordinalSU = 1;
384  zei->runNumber = 0;
385 
387  if (trec) /* targetInfo already exists ... */
388  {
389  data1_node *node_tgtinfo, *node_zebra, *node_list, *np;
390 
391  zei->data1_target = read_sgml_rec(zei->dh, zei->nmem, trec);
392 #if 0
393  if (!zei->data1_target || !zei->data1_target->u.root.absyn)
394 #else
395  if (!zei->data1_target)
396 #endif
397  {
398  yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
399  nmem_destroy(zei->nmem);
400  return 0;
401  }
402 #if ZINFO_DEBUG
403  data1_pr_tree(zei->dh, zei->data1_target, stderr);
404 #endif
405  node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
406  "/targetInfo");
407  if (!node_tgtinfo)
408  {
409  yaz_log(YLOG_FATAL, "Node node_tgtinfo missing");
410  nmem_destroy(zei->nmem);
411  return 0;
412  }
413  zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
414  &zei->accessInfo);
415 
416  node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
417  "zebraInfo");
418  if (!node_zebra)
419  {
420  yaz_log(YLOG_FATAL, "Node node_zebra missing");
421  nmem_destroy(zei->nmem);
422  return 0;
423  }
424  np = 0;
425  if (node_zebra)
426  {
427  node_list = data1_search_tag(zei->dh, node_zebra->child,
428  "databaseList");
429  if (node_list)
430  np = node_list->child;
431  }
432  for(; np; np = np->next)
433  {
434  data1_node *node_name = 0;
435  data1_node *node_id = 0;
436  data1_node *node_aid = 0;
437  data1_node *np2;
438  if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
439  continue;
440  for(np2 = np->child; np2; np2 = np2->next)
441  {
442  if (np2->which != DATA1N_tag)
443  continue;
444  if (!strcmp(np2->u.tag.tag, "name"))
445  node_name = np2->child;
446  else if (!strcmp(np2->u.tag.tag, "id"))
447  node_id = np2->child;
448  else if (!strcmp(np2->u.tag.tag, "attributeDetailsId"))
449  node_aid = np2->child;
450  }
451  assert(node_id && node_name && node_aid);
452 
453  *zdip =(struct zebDatabaseInfoB *)
454  nmem_malloc(zei->nmem, sizeof(**zdip));
455  (*zdip)->readFlag = 1;
456  (*zdip)->dirty = 0;
457  (*zdip)->data1_database = 0;
458  (*zdip)->recordCount = 0;
459  (*zdip)->recordBytes = 0;
460  zebraExplain_mergeAccessInfo(zei, 0, &(*zdip)->accessInfo);
461 
462  (*zdip)->databaseName = (char *)
463  nmem_malloc(zei->nmem, 1+node_name->u.data.len);
464  memcpy((*zdip)->databaseName, node_name->u.data.data,
465  node_name->u.data.len);
466  (*zdip)->databaseName[node_name->u.data.len] = '\0';
467  (*zdip)->sysno = atoi_zn(node_id->u.data.data,
468  node_id->u.data.len);
469  (*zdip)->attributeDetails = (zebAttributeDetails)
470  nmem_malloc(zei->nmem, sizeof(*(*zdip)->attributeDetails));
471  (*zdip)->attributeDetails->sysno = atoi_zn(node_aid->u.data.data,
472  node_aid->u.data.len);
473  (*zdip)->attributeDetails->readFlag = 1;
474  (*zdip)->attributeDetails->dirty = 0;
475  (*zdip)->attributeDetails->SUInfo = 0;
476 
477  zdip = &(*zdip)->next;
478  }
479  if (node_zebra)
480  {
481  np = data1_search_tag(zei->dh, node_zebra->child,
482  "ordinalSU");
483  np = np->child;
484  assert(np && np->which == DATA1N_data);
485  zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
486 
487  np = data1_search_tag(zei->dh, node_zebra->child,
488  "ordinalDatabase");
489  np = np->child;
490  assert(np && np->which == DATA1N_data);
491  zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
492 
493  np = data1_search_tag(zei->dh, node_zebra->child,
494  "runNumber");
495  np = np->child;
496  assert(np && np->which == DATA1N_data);
497  zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
498  yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
499  *zdip = 0;
500  }
501  rec_free(&trec);
502  }
503  else /* create initial targetInfo */
504  {
505  data1_node *node_tgtinfo;
506 
507  *zdip = 0;
508  if (writeFlag)
509  {
510  char *sgml_buf;
511  int sgml_len;
512 
513  zei->data1_target =
514  data1_read_sgml(zei->dh, zei->nmem,
515  "<explain><targetInfo>TargetInfo\n"
516  "<name>Zebra</>\n"
517  "<namedResultSets>1</>\n"
518  "<multipleDBSearch>1</>\n"
519  "<nicknames><name>Zebra</></>\n"
520  "</></>\n" );
521  if (!zei->data1_target)
522  {
523  yaz_log(YLOG_FATAL, "Explain schema missing. Check profilePath");
524  nmem_destroy(zei->nmem);
525  return 0;
526  }
527  node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
528  "/targetInfo");
529  assert(node_tgtinfo);
530 
531  zebraExplain_initCommonInfo(zei, node_tgtinfo);
532  zebraExplain_initAccessInfo(zei, node_tgtinfo);
533 
534  /* write now because we want to be sure about the sysno */
535  trec = rec_new(records);
536  if (!trec)
537  {
538  yaz_log(YLOG_FATAL, "Cannot create root Explain record");
539  nmem_destroy(zei->nmem);
540  return 0;
541  }
542  trec->info[recInfo_fileType] =
543  rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
544  trec->info[recInfo_databaseName] =
545  rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
546 
547  sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
548  trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
549  memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
550  trec->size[recInfo_storeData] = sgml_len;
551 
552  rec_put(records, &trec);
553  rec_free(&trec);
554  }
555 
556  zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
557 
558  if (!zei->categoryList->dirty)
559  {
560  struct zebraCategoryListInfo *zcl = zei->categoryList;
561  data1_node *node_cl;
562 
563  zcl->dirty = 1;
564  zcl->data1_categoryList =
565  data1_read_sgml(zei->dh, zei->nmem,
566  "<explain><categoryList>CategoryList\n"
567  "</></>\n");
568 
569  if (zcl->data1_categoryList)
570  {
571  node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
572  "/categoryList");
573  assert(node_cl);
574  zebraExplain_initCommonInfo(zei, node_cl);
575  }
576  }
577  }
578  return zei;
579 }
580 
583 {
584  Record rec;
585  struct zebSUInfoB **zsuip = &zad->SUInfo;
586  data1_node *node_adinfo, *node_zebra, *node_list, *np;
587 
588  assert(zad->sysno);
589  rec = rec_get(zei->records, zad->sysno);
590 
591  zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
592 
593  node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
594  "/attributeDetails");
595  node_zebra = data1_search_tag(zei->dh, node_adinfo->child,
596  "zebraInfo");
597  node_list = data1_search_tag(zei->dh, node_zebra->child,
598  "attrlist");
599  for (np = node_list->child; np; np = np->next)
600  {
601  data1_node *node_str = 0;
602  data1_node *node_ordinal = 0;
603  data1_node *node_type = 0;
604  data1_node *node_cat = 0;
605  data1_node *node_doc_occurrences = 0;
606  data1_node *node_term_occurrences = 0;
607  data1_node *np2;
608 
609  if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
610  continue;
611  for (np2 = np->child; np2; np2 = np2->next)
612  {
613  if (np2->which != DATA1N_tag || !np2->child ||
614  np2->child->which != DATA1N_data)
615  continue;
616  if (!strcmp(np2->u.tag.tag, "str"))
617  node_str = np2->child;
618  else if (!strcmp(np2->u.tag.tag, "ordinal"))
619  node_ordinal = np2->child;
620  else if (!strcmp(np2->u.tag.tag, "type"))
621  node_type = np2->child;
622  else if (!strcmp(np2->u.tag.tag, "cat"))
623  node_cat = np2->child;
624  else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
625  node_doc_occurrences = np2->child;
626  else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
627  node_term_occurrences = np2->child;
628  else
629  {
630  yaz_log(YLOG_LOG, "Unknown tag '%s' in attributeDetails",
631  np2->u.tag.tag);
632  }
633  }
634  assert(node_ordinal);
635 
636  *zsuip = (struct zebSUInfoB *)
637  nmem_malloc(zei->nmem, sizeof(**zsuip));
638 
639  if (node_type && node_type->u.data.len > 0)
640  (*zsuip)->info.index_type =
641  nmem_strdupn(zei->nmem,
642  node_type->u.data.data,
643  node_type->u.data.len);
644  else
645  {
646  yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
647  (*zsuip)->info.index_type = "w";
648  }
649  if (node_cat && node_cat->u.data.len > 0)
650  {
652 
653  data1_node *np = node_cat;
654  if (!strncmp(np->u.data.data, "index", np->u.data.len))
656  else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
658  else if (!strncmp(np->u.data.data, "alwaysmatches",
659  np->u.data.len))
661  else if (!strncmp(np->u.data.data, "anchor",
662  np->u.data.len))
664  else
665  {
666  yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
667  np->u.data.len, np->u.data.data);
669  }
670  (*zsuip)->info.cat = cat;
671  }
672  else
673  (*zsuip)->info.cat = zinfo_index_category_index;
674 
675  if (node_doc_occurrences)
676  {
677  data1_node *np = node_doc_occurrences;
678  (*zsuip)->info.doc_occurrences = atoi_zn(np->u.data.data,
679  np->u.data.len);
680  }
681  if (node_term_occurrences)
682  {
683  data1_node *np = node_term_occurrences;
684  (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
685  np->u.data.len);
686  }
687  if (node_str)
688  {
689  (*zsuip)->info.str = nmem_strdupn(zei->nmem,
690  node_str->u.data.data,
691  node_str->u.data.len);
692  }
693  else
694  {
695  yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
696  continue;
697  }
698  (*zsuip)->info.ordinal = atoi_n(node_ordinal->u.data.data,
699  node_ordinal->u.data.len);
700  zsuip = &(*zsuip)->next;
701  }
702  *zsuip = 0;
703  zad->readFlag = 0;
704  rec_free(&rec);
705 }
706 
708  struct zebDatabaseInfoB *zdi)
709 {
710  Record rec;
711  data1_node *node_dbinfo, *node_zebra, *np;
712 
713  assert(zdi->sysno);
714  rec = rec_get(zei->records, zdi->sysno);
715 
716  zdi->data1_database = read_sgml_rec(zei->dh, zei->nmem, rec);
717 
718  node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
719  "/databaseInfo");
720  assert(node_dbinfo);
721  zebraExplain_mergeAccessInfo(zei, node_dbinfo, &zdi->accessInfo);
722 
723  node_zebra = data1_search_tag(zei->dh, node_dbinfo->child,
724  "zebraInfo");
725  if (node_zebra
726  && (np = data1_search_tag(zei->dh, node_zebra->child,
727  "recordBytes"))
728  && np->child && np->child->which == DATA1N_data)
729  zdi->recordBytes = atoi_zn(np->child->u.data.data,
730  np->child->u.data.len);
731 
732  if (node_zebra
733  && (np = data1_search_tag(zei->dh, node_zebra->child,
734  "ordinalDatabase"))
735  && np->child && np->child->which == DATA1N_data)
736  zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
737  np->child->u.data.len);
738 
739  if ((np = data1_search_tag(zei->dh, node_dbinfo->child,
740  "recordCount")) &&
741  (np = data1_search_tag(zei->dh, np->child,
742  "recordCountActual")) &&
743  np->child->which == DATA1N_data)
744  {
745  zdi->recordCount = atoi_zn(np->child->u.data.data,
746  np->child->u.data.len);
747  }
748  zdi->readFlag = 0;
749  rec_free(&rec);
750 }
751 
752 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
753 {
754  struct zebDatabaseInfoB **zdip = &zei->databaseInfo;
755 
756  while (*zdip)
757  {
758  if (*zdip == zei->curDatabaseInfo)
759  {
760  struct zebDatabaseInfoB *zdi = *zdip;
761  Record rec;
762 
763  zei->dirty = 1;
764  zei->updateHandle = update_handle;
765 
766  if (zdi->attributeDetails)
767  {
768  /* remove attribute details keys and delete it */
770 
771  rec = rec_get(zei->records, zad->sysno);
772  (*zei->updateFunc)(zei->updateHandle, rec, 0);
773  rec_del(zei->records, &rec);
774  }
775  /* remove database record keys and delete it */
776  rec = rec_get(zei->records, zdi->sysno);
777  (*zei->updateFunc)(zei->updateHandle, rec, 0);
778  rec_del(zei->records, &rec);
779 
780  /* remove from list */
781  *zdip = zdi->next;
782 
783  /* current database is IR-Explain-1 */
784  return 0;
785  }
786  zdip = &(*zdip)->next;
787  }
788  return -1;
789 }
790 
791 int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
792 {
793  struct zebDatabaseInfoB *zdi;
794  const char *database_n = strrchr(database, '/');
795 
796  if (database_n)
797  database_n++;
798  else
799  database_n = database;
800 
801  assert(zei);
802  if (zei->curDatabaseInfo &&
803  !STRCASECMP(zei->curDatabaseInfo->databaseName, database))
804  return 0;
805  for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
806  {
807  if (!STRCASECMP(zdi->databaseName, database_n))
808  break;
809  }
810  if (!zdi)
811  return -1;
812 #if ZINFO_DEBUG
813  yaz_log(YLOG_LOG, "zebraExplain_curDatabase: %s", database);
814 #endif
815  if (zdi->readFlag)
816  {
817 #if ZINFO_DEBUG
818  yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
819 #endif
820  zebraExplain_readDatabase(zei, zdi);
821  }
822  if (zdi->attributeDetails->readFlag)
823  {
824 #if ZINFO_DEBUG
825  yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
826 #endif
828  }
829  zei->curDatabaseInfo = zdi;
830  return 0;
831 }
832 
834 {
835  data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "commonInfo", 0, n);
836  data1_mk_tag_data_text(zei->dh, c, "dateAdded", zei->date, zei->nmem);
837  data1_mk_tag_data_text(zei->dh, c, "dateChanged", zei->date, zei->nmem);
838  data1_mk_tag_data_text(zei->dh, c, "languageCode", "EN", zei->nmem);
839 }
840 
842 {
843  data1_node *c = data1_search_tag(zei->dh, n->child, "commonInfo");
844  assert(c);
845  data1_mk_tag_data_text_uni(zei->dh, c, "dateChanged", zei->date,
846  zei->nmem);
847 }
848 
850 {
851  data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "accessInfo", 0, n);
852  data1_node *d = data1_mk_tag(zei->dh, zei->nmem, "unitSystems", 0, c);
853  data1_mk_tag_data_text(zei->dh, d, "string", "ISO", zei->nmem);
854 }
855 
857  zebAccessInfo accessInfo)
858 {
859  data1_node *c = data1_search_tag(zei->dh, n->child, "accessInfo");
860  data1_node *d;
861  zebAccessObject p;
862 
863  if (!c)
864  {
865  data1_pr_tree(zei->dh, n, stdout);
866  zebra_exit("zebraExplain_updateAccessInfo");
867  }
868 
869  if ((p = accessInfo->attributeSetIds))
870  {
871  d = data1_mk_tag_uni(zei->dh, zei->nmem, "attributeSetIds", c);
872  for (; p; p = p->next)
873  data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
874  }
875  if ((p = accessInfo->schemas))
876  {
877  d = data1_mk_tag_uni(zei->dh, zei->nmem, "schemas", c);
878  for (; p; p = p->next)
879  data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
880  }
881 }
882 
883 int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database,
884  int explain_database)
885 {
886  struct zebDatabaseInfoB *zdi;
887  data1_node *node_dbinfo, *node_adinfo;
888  const char *database_n = strrchr(database, '/');
889 
890  if (database_n)
891  database_n++;
892  else
893  database_n = database;
894 
895 #if ZINFO_DEBUG
896  yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
897 #endif
898  assert(zei);
899  for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
900  {
901  if (!STRCASECMP(zdi->databaseName, database_n))
902  break;
903  }
904  if (zdi)
905  return -1;
906  /* it's new really. make it */
907  zdi = (struct zebDatabaseInfoB *) nmem_malloc(zei->nmem, sizeof(*zdi));
908  zdi->next = zei->databaseInfo;
909  zei->databaseInfo = zdi;
910  zdi->sysno = 0;
911  zdi->recordCount = 0;
912  zdi->recordBytes = 0;
913  zdi->readFlag = 0;
914  zdi->databaseName = nmem_strdup(zei->nmem, database_n);
915 
916  zdi->ordinalDatabase = zei->ordinalDatabase++;
917 
919 
920  assert(zei->dh);
921  assert(zei->nmem);
922 
923  zdi->data1_database =
924  data1_read_sgml(zei->dh, zei->nmem,
925  "<explain><databaseInfo>DatabaseInfo\n"
926  "</></>\n");
927  if (!zdi->data1_database)
928  return -2;
929 
930  node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
931  "/databaseInfo");
932  assert(node_dbinfo);
933 
934  zebraExplain_initCommonInfo(zei, node_dbinfo);
935  zebraExplain_initAccessInfo(zei, node_dbinfo);
936 
937  data1_mk_tag_data_text(zei->dh, node_dbinfo, "name",
938  database, zei->nmem);
939 
940  if (explain_database)
941  data1_mk_tag_data_text(zei->dh, node_dbinfo, "explainDatabase",
942  "", zei->nmem);
943 
944  data1_mk_tag_data_text(zei->dh, node_dbinfo, "userFee",
945  "0", zei->nmem);
946 
947  data1_mk_tag_data_text(zei->dh, node_dbinfo, "available",
948  "1", zei->nmem);
949 
950 #if ZINFO_DEBUG
951  data1_pr_tree(zei->dh, zdi->data1_database, stderr);
952 #endif
953  zdi->dirty = 1;
954  zei->dirty = 1;
955  zei->curDatabaseInfo = zdi;
956 
958  nmem_malloc(zei->nmem, sizeof(*zdi->attributeDetails));
959  zdi->attributeDetails->readFlag = 0;
960  zdi->attributeDetails->sysno = 0;
961  zdi->attributeDetails->dirty = 1;
962  zdi->attributeDetails->SUInfo = 0;
964  data1_read_sgml(zei->dh, zei->nmem,
965  "<explain><attributeDetails>AttributeDetails\n"
966  "</></>\n");
967 
968  node_adinfo = data1_search_tag(zei->dh, zdi->attributeDetails->data1_tree,
969  "/attributeDetails");
970  assert(node_adinfo);
971 
972  zebraExplain_initCommonInfo(zei, node_adinfo);
973 
974  data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
975 
976  return 0;
977 }
978 
979 
981  struct zebraCategoryListInfo *zcl,
982  int key_flush)
983 {
984  char *sgml_buf;
985  int sgml_len;
986  int i;
987  Record drec;
988  data1_node *node_ci, *node_categoryList;
989  zint sysno = 0;
990  static char *category[] = {
991  "CategoryList",
992  "TargetInfo",
993  "DatabaseInfo",
994  "AttributeDetails",
995  0
996  };
997 
998  assert(zcl);
999  if (!zcl->dirty)
1000  return ;
1001  zcl->dirty = 0;
1002  node_categoryList = zcl->data1_categoryList;
1003 
1004 #if ZINFO_DEBUG
1005  yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
1006 #endif
1007 
1008  drec = createRecord(zei->records, &sysno);
1009  if (!drec)
1010  return;
1011 
1012  node_ci = data1_search_tag(zei->dh, node_categoryList,
1013  "/categoryList");
1014  assert (node_ci);
1015  node_ci = data1_mk_tag(zei->dh, zei->nmem, "categories", 0 /* attr */,
1016  node_ci);
1017  assert (node_ci);
1018 
1019  for (i = 0; category[i]; i++)
1020  {
1021  data1_node *node_cat = data1_mk_tag(zei->dh, zei->nmem, "category",
1022  0 /* attr */, node_ci);
1023 
1024  data1_mk_tag_data_text(zei->dh, node_cat, "name",
1025  category[i], zei->nmem);
1026  }
1027  /* extract *searchable* keys from it. We do this here, because
1028  record count, etc. is affected */
1029  if (key_flush)
1030  (*zei->updateFunc)(zei->updateHandle, drec, node_categoryList);
1031 
1032  /* convert to "SGML" and write it */
1033 #if ZINFO_DEBUG
1034  data1_pr_tree(zei->dh, node_categoryList, stderr);
1035 #endif
1036  sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
1037  drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1038  memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1039  drec->size[recInfo_storeData] = sgml_len;
1040 
1041  rec_put(zei->records, &drec);
1042 }
1043 
1045  zebAttributeDetails zad,
1046  const char *databaseName,
1047  int key_flush)
1048 {
1049  char *sgml_buf;
1050  int sgml_len;
1051  Record drec;
1052  data1_node *node_adinfo, *node_list, *node_zebra;
1053  struct zebSUInfoB *zsui;
1054 
1055  if (!zad->dirty)
1056  return;
1057 
1058  zad->dirty = 0;
1059 #if ZINFO_DEBUG
1060  yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
1061  data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1062 #endif
1063 
1064  drec = createRecord(zei->records, &zad->sysno);
1065  if (!drec)
1066  return;
1067  assert(zad->data1_tree);
1068 
1069  node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
1070  "/attributeDetails");
1071  zebraExplain_updateCommonInfo(zei, node_adinfo);
1072 
1073  /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
1074  node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1075  "zebraInfo", node_adinfo);
1076 
1077  /* extract *searchable* keys from it. We do this here, because
1078  record count, etc. is affected */
1079  if (key_flush)
1080  (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
1081  node_list = data1_mk_tag_uni(zei->dh, zei->nmem,
1082  "attrlist", node_zebra);
1083  for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
1084  {
1085  data1_node *node_attr;
1086  node_attr = data1_mk_tag(zei->dh, zei->nmem, "attr", 0 /* attr */,
1087  node_list);
1088 
1089  data1_mk_tag_data_text(zei->dh, node_attr, "type",
1090  zsui->info.index_type, zei->nmem);
1091  data1_mk_tag_data_text(zei->dh, node_attr, "str",
1092  zsui->info.str, zei->nmem);
1093  data1_mk_tag_data_int(zei->dh, node_attr, "ordinal",
1094  zsui->info.ordinal, zei->nmem);
1095 
1096  data1_mk_tag_data_zint(zei->dh, node_attr, "dococcurrences",
1097  zsui->info.doc_occurrences, zei->nmem);
1098  data1_mk_tag_data_zint(zei->dh, node_attr, "termoccurrences",
1099  zsui->info.term_occurrences, zei->nmem);
1100  switch(zsui->info.cat)
1101  {
1103  data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1104  "index", zei->nmem); break;
1106  data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1107  "sort", zei->nmem); break;
1109  data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1110  "alwaysmatches", zei->nmem); break;
1112  data1_mk_tag_data_text(zei->dh, node_attr, "cat",
1113  "anchor", zei->nmem); break;
1114  }
1115  }
1116  /* convert to "SGML" and write it */
1117 #if ZINFO_DEBUG
1118  data1_pr_tree(zei->dh, zad->data1_tree, stderr);
1119 #endif
1120  sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
1121  0, &sgml_len);
1122  drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1123  memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1124  drec->size[recInfo_storeData] = sgml_len;
1125 
1126  rec_put(zei->records, &drec);
1127 }
1128 
1130  struct zebDatabaseInfoB *zdi,
1131  int key_flush)
1132 {
1133  char *sgml_buf;
1134  int sgml_len;
1135  Record drec;
1136  data1_node *node_dbinfo, *node_count, *node_zebra;
1137 
1138  if (!zdi->dirty)
1139  return;
1140 
1141  zdi->dirty = 0;
1142 #if ZINFO_DEBUG
1143  yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
1144 #endif
1145  drec = createRecord(zei->records, &zdi->sysno);
1146  if (!drec)
1147  return;
1148  assert(zdi->data1_database);
1149 
1150  node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
1151  "/databaseInfo");
1152 
1153  assert(node_dbinfo);
1154  zebraExplain_updateCommonInfo(zei, node_dbinfo);
1155  zebraExplain_updateAccessInfo(zei, node_dbinfo, zdi->accessInfo);
1156 
1157  /* record count */
1158  node_count = data1_mk_tag_uni(zei->dh, zei->nmem,
1159  "recordCount", node_dbinfo);
1160  data1_mk_tag_data_zint(zei->dh, node_count, "recordCountActual",
1161  zdi->recordCount, zei->nmem);
1162 
1163  /* zebra info (private) */
1164  node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1165  "zebraInfo", node_dbinfo);
1166 
1167  /* extract *searchable* keys from it. We do this here, because
1168  record count, etc. is affected */
1169  if (key_flush)
1170  (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
1171  data1_mk_tag_data_zint(zei->dh, node_zebra,
1172  "recordBytes", zdi->recordBytes, zei->nmem);
1173 
1174  data1_mk_tag_data_zint(zei->dh, node_zebra,
1175  "ordinalDatabase", zdi->ordinalDatabase, zei->nmem);
1176 
1177  /* convert to "SGML" and write it */
1178 #if ZINFO_DEBUG
1179  data1_pr_tree(zei->dh, zdi->data1_database, stderr);
1180 #endif
1181  sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
1182  0, &sgml_len);
1183  drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1184  memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1185  drec->size[recInfo_storeData] = sgml_len;
1186 
1187  rec_put(zei->records, &drec);
1188 }
1189 
1191  data1_node *node_values,
1192  data1_attset *attset)
1193 {
1194  data1_att *atts;
1195  data1_attset_child *c;
1196 
1197  if (!attset)
1198  return;
1199 
1200  for (c = attset->children; c; c = c->next)
1201  writeAttributeValues(zei, node_values, c->child);
1202  for (atts = attset->atts; atts; atts = atts->next)
1203  {
1204  data1_node *node_value;
1205 
1206  node_value = data1_mk_tag(zei->dh, zei->nmem, "attributeValue",
1207  0 /* attr */, node_values);
1208  data1_mk_tag_data_text(zei->dh, node_value, "name",
1209  atts->name, zei->nmem);
1210  node_value = data1_mk_tag(zei->dh, zei->nmem, "value",
1211  0 /* attr */, node_value);
1212  data1_mk_tag_data_int(zei->dh, node_value, "numeric",
1213  atts->value, zei->nmem);
1214  }
1215 }
1216 
1217 
1219  zebAccessObject o,
1220  int key_flush)
1221 {
1222  char *sgml_buf;
1223  int sgml_len;
1224  Record drec;
1225  data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
1226  data1_node *node_values;
1227  struct data1_attset *attset = 0;
1228 
1229  if (o->oid)
1230  attset = data1_attset_search_id(zei->dh, o->oid);
1231 
1232 #if ZINFO_DEBUG
1233  yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
1234  attset ? attset->name : "<unknown>");
1235 #endif
1236 
1237  drec = createRecord(zei->records, &o->sysno);
1238  if (!drec)
1239  return;
1240  node_root =
1241  data1_read_sgml(zei->dh, zei->nmem,
1242  "<explain><attributeSetInfo>AttributeSetInfo\n"
1243  "</></>\n" );
1244 
1245  node_attinfo = data1_search_tag(zei->dh, node_root,
1246  "/attributeSetInfo");
1247 
1248  assert(node_attinfo);
1249  zebraExplain_initCommonInfo(zei, node_attinfo);
1250  zebraExplain_updateCommonInfo(zei, node_attinfo);
1251 
1252  data1_mk_tag_data_oid(zei->dh, node_attinfo,
1253  "oid", o->oid, zei->nmem);
1254  if (attset && attset->name)
1255  data1_mk_tag_data_text(zei->dh, node_attinfo,
1256  "name", attset->name, zei->nmem);
1257 
1258  node_attributes = data1_mk_tag_uni(zei->dh, zei->nmem,
1259  "attributes", node_attinfo);
1260  node_atttype = data1_mk_tag_uni(zei->dh, zei->nmem,
1261  "attributeType", node_attributes);
1262  data1_mk_tag_data_text(zei->dh, node_atttype,
1263  "name", "Use", zei->nmem);
1264  data1_mk_tag_data_text(zei->dh, node_atttype,
1265  "description", "Use Attribute", zei->nmem);
1266  data1_mk_tag_data_int(zei->dh, node_atttype,
1267  "type", 1, zei->nmem);
1268  node_values = data1_mk_tag(zei->dh, zei->nmem,
1269  "attributeValues", 0 /* attr */, node_atttype);
1270  if (attset)
1271  writeAttributeValues(zei, node_values, attset);
1272 
1273  /* extract *searchable* keys from it. We do this here, because
1274  record count, etc. is affected */
1275  if (key_flush)
1276  (*zei->updateFunc)(zei->updateHandle, drec, node_root);
1277  /* convert to "SGML" and write it */
1278 #if ZINFO_DEBUG
1279  data1_pr_tree(zei->dh, node_root, stderr);
1280 #endif
1281  sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
1282  drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1283  memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
1284  drec->size[recInfo_storeData] = sgml_len;
1285 
1286  rec_put(zei->records, &drec);
1287 }
1288 
1289 static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush)
1290 {
1291  struct zebDatabaseInfoB *zdi;
1292  data1_node *node_tgtinfo, *node_list, *node_zebra;
1293  Record trec;
1294  int sgml_len;
1295  char *sgml_buf;
1296 
1297  if (!zei->dirty)
1298  return;
1299  zei->dirty = 0;
1300 
1301  trec = rec_get_root(zei->records);
1302  xfree(trec->info[recInfo_storeData]);
1303 
1304  node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
1305  "/targetInfo");
1306  assert(node_tgtinfo);
1307 
1308  zebraExplain_updateCommonInfo(zei, node_tgtinfo);
1309  zebraExplain_updateAccessInfo(zei, node_tgtinfo, zei->accessInfo);
1310 
1311  node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
1312  "zebraInfo", node_tgtinfo);
1313  /* convert to "SGML" and write it */
1314  if (key_flush)
1315  (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
1316 
1317  data1_mk_tag_data_text(zei->dh, node_zebra, "version",
1318  ZEBRAVER, zei->nmem);
1319  node_list = data1_mk_tag(zei->dh, zei->nmem,
1320  "databaseList", 0 /* attr */, node_zebra);
1321  for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
1322  {
1323  data1_node *node_db;
1324  node_db = data1_mk_tag(zei->dh, zei->nmem,
1325  "database", 0 /* attr */, node_list);
1326  data1_mk_tag_data_text(zei->dh, node_db, "name",
1327  zdi->databaseName, zei->nmem);
1328  data1_mk_tag_data_zint(zei->dh, node_db, "id",
1329  zdi->sysno, zei->nmem);
1330  data1_mk_tag_data_zint(zei->dh, node_db, "attributeDetailsId",
1331  zdi->attributeDetails->sysno, zei->nmem);
1332  }
1333  data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalSU",
1334  zei->ordinalSU, zei->nmem);
1335 
1336  data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalDatabase",
1337  zei->ordinalDatabase, zei->nmem);
1338 
1339  data1_mk_tag_data_zint(zei->dh, node_zebra, "runNumber",
1340  zei->runNumber, zei->nmem);
1341 
1342 #if ZINFO_DEBUG
1343  data1_pr_tree(zei->dh, zei->data1_target, stderr);
1344 #endif
1345  sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
1346  0, &sgml_len);
1347  trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
1348  memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
1349  trec->size[recInfo_storeData] = sgml_len;
1350 
1351  rec_put(zei->records, &trec);
1352 }
1353 
1356  const char *index_type,
1357  const char *str)
1358 {
1359  struct zebSUInfoB **zsui;
1360 
1361  assert(zei->curDatabaseInfo);
1362  for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
1363  *zsui; zsui = &(*zsui)->next)
1364  if ( (index_type == 0
1365  || !strcmp((*zsui)->info.index_type, index_type))
1366  && (*zsui)->info.cat == cat
1367  && !yaz_matchstr((*zsui)->info.str, str))
1368  {
1369  struct zebSUInfoB *zsui_this = *zsui;
1370 
1371  /* take it out of the list and move to front */
1372  *zsui = (*zsui)->next;
1373  zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
1374  zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
1375 
1376  return zsui_this->info.ordinal;
1377  }
1378  return -1;
1379 }
1380 
1382  int (*f)(void *handle, int ord,
1383  const char *index_type,
1384  const char *string_index,
1386 {
1387  struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
1388  if (zdb)
1389  {
1390  struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
1391  for ( ;zsui; zsui = zsui->next)
1392  (*f)(handle, zsui->info.ordinal,
1393  zsui->info.index_type, zsui->info.str,
1394  zsui->info.cat);
1395  }
1396  return 0;
1397 }
1398 
1399 
1401  int dirty_mark,
1402  const char **db)
1403 {
1404  struct zebDatabaseInfoB *zdb;
1405 
1406  for (zdb = zei->databaseInfo; zdb; zdb = zdb->next)
1407  {
1408  struct zebSUInfoB **zsui;
1409 
1410  if (zdb->attributeDetails->readFlag)
1412 
1413  for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
1414  zsui = &(*zsui)->next)
1415  if ((*zsui)->info.ordinal == ord)
1416  {
1417  struct zebSUInfoB *zsui_this = *zsui;
1418 
1419  /* take it out of the list and move to front */
1420  *zsui = (*zsui)->next;
1421  zsui_this->next = zdb->attributeDetails->SUInfo;
1422  zdb->attributeDetails->SUInfo = zsui_this;
1423 
1424  if (dirty_mark)
1425  zdb->attributeDetails->dirty = 1;
1426  if (db)
1427  *db = zdb->databaseName;
1428  return zsui_this;
1429  }
1430  }
1431  return 0;
1432 }
1433 
1434 
1435 
1437  int term_delta, int doc_delta)
1438 {
1439  struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 1, 0);
1440  if (zsui)
1441  {
1442  zsui->info.term_occurrences += term_delta;
1443  zsui->info.doc_occurrences += doc_delta;
1444  return 0;
1445  }
1446  return -1;
1447 }
1448 
1452 {
1453  struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1454  if (zsui)
1455  {
1456  *term_occurrences = zsui->info.term_occurrences;
1457  *doc_occurrences = zsui->info.doc_occurrences;
1458  return 0;
1459  }
1460  return -1;
1461 }
1462 
1464 {
1465  struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1466  if (zsui)
1467  return zsui->info.doc_occurrences;
1468  return 0;
1469 }
1470 
1472 {
1473  struct zebSUInfoB *zsui = zebraExplain_get_sui_info(zei, ord, 0, 0);
1474  if (zsui)
1475  return zsui->info.term_occurrences;
1476  return 0;
1477 }
1478 
1480  const char **index_type,
1481  const char **db,
1482  const char **string_index)
1483 {
1484  struct zebSUInfoB *zsui;
1485 
1486  if (index_type)
1487  *index_type = 0;
1488  if (string_index)
1489  *string_index = 0;
1490 
1491  zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
1492  if (zsui)
1493  {
1494  if (string_index)
1495  *string_index = zsui->info.str;
1496  if (index_type)
1497  *index_type = zsui->info.index_type;
1498  return 0;
1499  }
1500  return -1;
1501 }
1502 
1503 
1504 
1506  zebAccessObject *op,
1507  Odr_oid *oid)
1508 {
1509  zebAccessObject ao;
1510 
1511  for (ao = *op; ao; ao = ao->next)
1512  if (!oid_oidcmp(oid, ao->oid))
1513  break;
1514  if (!ao)
1515  {
1516  ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
1517  ao->handle = 0;
1518  ao->sysno = 0;
1519  ao->oid = odr_oiddup_nmem(zei->nmem, oid);
1520  ao->next = *op;
1521  *op = ao;
1522  }
1523  return ao;
1524 }
1525 
1528  const char *index_type)
1529 {
1530  struct zebSUInfoB *zsui;
1531 
1532  assert(zei->curDatabaseInfo);
1533  zsui = (struct zebSUInfoB *) nmem_malloc(zei->nmem, sizeof(*zsui));
1535  zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
1537  zei->dirty = 1;
1538  zsui->info.index_type = nmem_strdup(zei->nmem, index_type);
1539  zsui->info.cat = cat;
1540  zsui->info.doc_occurrences = 0;
1541  zsui->info.term_occurrences = 0;
1542  zsui->info.ordinal = (zei->ordinalSU)++;
1543  return zsui;
1544 }
1545 
1548  const char *index_type,
1549  const char *index_name)
1550 {
1551  struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
1552 
1553  zsui->info.str = nmem_strdup(zei->nmem, index_name);
1554  return zsui->info.ordinal;
1555 }
1556 
1558 {
1559  zebraExplain_announceOid(zei, &zei->accessInfo->schemas, oid);
1561  accessInfo->schemas, oid);
1562 }
1563 
1565 {
1566  assert(zei->curDatabaseInfo);
1567 
1568  if (adjust_num)
1569  {
1570  zei->curDatabaseInfo->recordBytes += adjust_num;
1571  zei->curDatabaseInfo->dirty = 1;
1572  }
1573 }
1574 
1576 {
1577  assert(zei->curDatabaseInfo);
1578 
1579  if (adjust_num)
1580  {
1581  zei->curDatabaseInfo->recordCount += adjust_num;
1582  zei->curDatabaseInfo->dirty = 1;
1583  }
1584 }
1585 
1587 {
1588  if (adjust_num)
1589  {
1590  zei->dirty = 1;
1591  }
1592  return zei->runNumber += adjust_num;
1593 }
1594 
1596 {
1597  RecordAttr *recordAttr;
1598 
1599  if (rec->info[recInfo_attr])
1600  return (RecordAttr *) rec->info[recInfo_attr];
1601  recordAttr = (RecordAttr *) xmalloc(sizeof(*recordAttr));
1602 
1603  memset(recordAttr, '\0', sizeof(*recordAttr));
1604  rec->info[recInfo_attr] = (char *) recordAttr;
1605  rec->size[recInfo_attr] = sizeof(*recordAttr);
1606 
1607  recordAttr->recordSize = 0;
1608  recordAttr->recordOffset = 0;
1609  recordAttr->runNumber = zei->runNumber;
1610  recordAttr->staticrank = 0;
1611  return recordAttr;
1612 }
1613 
1614 static void att_loadset(void *p, const char *n, const char *name)
1615 {
1616  data1_handle dh = (data1_handle) p;
1617  if (!data1_get_attset(dh, name))
1618  yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
1619 }
1620 
1622 {
1623  if (!zei->curDatabaseInfo)
1624  return -1;
1625  return zei->curDatabaseInfo->ordinalDatabase;
1626 }
1627 
1629 {
1630  res_trav(res, "attset", dh, att_loadset);
1631 }
1632 
1633 /*
1634  zebraExplain_addSU adds to AttributeDetails for a database and
1635  adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
1636  exist for the database.
1637 
1638  If the database doesn't exist globally (in TargetInfo) an
1639  AttributeSetInfo must be added (globally).
1640  */
1641 /*
1642  * Local variables:
1643  * c-basic-offset: 4
1644  * c-file-style: "Stroustrup"
1645  * indent-tabs-mode: nil
1646  * End:
1647  * vim: shiftwidth=4 tabstop=8 expandtab
1648  */
1649 
Record rec_get(Records p, zint sysno)
gets record - with given system number
Definition: records.c:927
struct zebSUInfo info
Definition: zinfo.c:44
zint doc_occurrences
Definition: zinfo.c:39
zint atoi_zn(const char *buf, zint len)
Definition: atoi_zn.c:27
#define DATA1N_tag
Definition: data1.h:276
char * rec_strdup(const char *s, size_t *len)
Definition: records.c:1079
char * str
Definition: zinfo.c:37
data1_absyn * data1_get_absyn(data1_handle dh, const char *name, enum DATA1_XPATH_INDEXING en)
Definition: d1_absyn.c:230
off_t recordOffset
Definition: zinfo.h:107
static void zebraExplain_updateCommonInfo(ZebraExplainInfo zei, data1_node *n)
Definition: zinfo.c:841
const char * res_get_def(Res r, const char *name, const char *def)
Definition: res.c:313
struct zebDatabaseInfoB * next
Definition: zinfo.c:80
struct zebAccessInfoB * zebAccessInfo
Definition: zinfo.c:56
int readFlag
Definition: zinfo.c:78
int recordSize
Definition: zinfo.h:106
data1_node * data1_read_sgml(data1_handle dh, NMEM m, const char *buf)
Definition: d1_read.c:1000
void zebraExplain_loadAttsets(data1_handle dh, Res res)
Definition: zinfo.c:1628
char * name
Definition: data1.h:70
void zebraExplain_flush(ZebraExplainInfo zei, void *handle)
Definition: zinfo.c:167
struct zebraExplainAttset * attsets
Definition: zinfo.c:105
int ordinal
Definition: zinfo.c:38
ZebraExplainInfo zebraExplain_open(Records records, data1_handle dh, Res res, int writeFlag, void *updateHandle, ZebraExplainUpdateFunc *updateFunc)
Definition: zinfo.c:330
data1_node * data1_mk_tag_data_oid(data1_handle dh, data1_node *at, const char *tag, Odr_oid *oid, NMEM nmem)
Definition: d1_read.c:480
data1_node * data1_mk_tag_data_text(data1_handle dh, data1_node *at, const char *tag, const char *str, NMEM nmem)
Definition: d1_read.c:506
zint zebraExplain_runNumberIncrement(ZebraExplainInfo zei, int adjust_num)
Definition: zinfo.c:1586
int value
Definition: data1.h:59
struct zebraExplainInfo * ZebraExplainInfo
Definition: zinfo.h:48
Records records
Definition: zinfo.c:102
char date[15]
Definition: zinfo.c:112
int ordinalDatabase
Definition: zinfo.c:98
struct zebSUInfoB * SUInfo
Definition: zinfo.c:63
void data1_pr_tree(data1_handle dh, data1_node *n, FILE *out)
Definition: d1_prtree.c:134
zint runNumber
Definition: zinfo.c:99
char * index_type
Definition: zinfo.c:35
static Record createRecord(Records records, zint *sysno)
Definition: zinfo.c:141
data1_att * next
Definition: data1.h:60
int write_flag
Definition: zinfo.c:101
static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush)
Definition: zinfo.c:1289
ZEBRA_RES ZebraExplainUpdateFunc(void *handle, Record drec, data1_node *n)
Definition: zinfo.h:44
#define ZEBRAVER
Version as string.
Definition: version.h:28
struct zebDatabaseInfoB * databaseInfo
Definition: zinfo.c:109
int ordinalSU
Definition: zinfo.c:97
data1_node * data1_mk_tag_uni(data1_handle dh, NMEM nmem, const char *tag, data1_node *at)
Definition: d1_read.c:319
int zebraExplain_add_attr_str(ZebraExplainInfo zei, zinfo_index_category_t cat, const char *index_type, const char *index_name)
Definition: zinfo.c:1546
void rec_free(Record *recpp)
frees record (from memory)
Definition: records.c:1043
data1_node * data1_mk_tag_data_zint(data1_handle dh, data1_node *at, const char *tag, zint num, NMEM nmem)
Definition: d1_read.c:457
void zebraExplain_mergeOids(ZebraExplainInfo zei, data1_node *n, zebAccessObject *op)
Definition: zinfo.c:219
zebAccessObject schemas
Definition: zinfo.c:59
zebAccessObject zebraExplain_announceOid(ZebraExplainInfo zei, zebAccessObject *op, Odr_oid *oid)
Definition: zinfo.c:1505
static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n)
Definition: zinfo.c:833
data1_att * atts
Definition: data1.h:72
zebAccessObject attributeSetIds
Definition: zinfo.c:58
data1_node * data1_mk_tag(data1_handle dh, NMEM nmem, const char *tag, const char **attr, data1_node *at)
Definition: d1_read.c:294
int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, zinfo_index_category_t cat, const char *index_type, const char *str)
lookup ordinal from string index + index type
Definition: zinfo.c:1354
zint staticrank
Definition: zinfo.h:109
int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
Definition: zinfo.c:752
static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei, zebAccessObject o, int key_flush)
Definition: zinfo.c:1218
data1_node * data1_database
Definition: zinfo.c:74
void zebraExplain_recordBytesIncrement(ZebraExplainInfo zei, int adjust_num)
Definition: zinfo.c:1564
struct zebSUInfoB * next
Definition: zinfo.c:45
struct zebraExplainAttset * next
Definition: zinfo.c:87
static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n)
Definition: zinfo.c:849
int ordinalDatabase
Definition: zinfo.c:72
static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei, zebAttributeDetails zad)
Definition: zinfo.c:581
size_t size[REC_NO_INFO]
Definition: recindex.h:35
static data1_node * read_sgml_rec(data1_handle dh, NMEM nmem, Record rec)
Definition: zinfo.c:120
zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
Definition: zinfo.c:1471
int zebraExplain_ord_get_occurrences(ZebraExplainInfo zei, int ord, zint *term_occurrences, zint *doc_occurrences)
Definition: zinfo.c:1449
Definition: res.c:46
static void zebraExplain_writeDatabase(ZebraExplainInfo zei, struct zebDatabaseInfoB *zdi, int key_flush)
Definition: zinfo.c:1129
static void zebraExplain_writeCategoryList(ZebraExplainInfo zei, struct zebraCategoryListInfo *zcl, int key_flush)
Definition: zinfo.c:980
int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database, int explain_database)
Definition: zinfo.c:883
data1_attset * data1_attset_search_id(data1_handle dh, const Odr_oid *oid)
Definition: d1_absyn.c:253
zint zebraExplain_ord_get_doc_occurrences(ZebraExplainInfo zei, int ord)
Definition: zinfo.c:1463
static void writeAttributeValues(ZebraExplainInfo zei, data1_node *node_values, data1_attset *attset)
Definition: zinfo.c:1190
zebAttributeDetails attributeDetails
Definition: zinfo.c:71
zint sysno
Definition: zinfo.c:77
struct zebAccessObjectB * zebAccessObject
Definition: zinfo.c:48
char * tag
Definition: data1.h:296
int res_trav(Res r, const char *prefix, void *p, void(*f)(void *p, const char *name, const char *value))
Definition: res.c:357
void * updateHandle
Definition: zinfo.c:114
void zebraExplain_addSchema(ZebraExplainInfo zei, Odr_oid *oid)
Definition: zinfo.c:1557
union data1_node::@2 u
char * info[REC_NO_INFO]
Definition: recindex.h:34
struct data1_node::@2::@3 root
data1_attset * child
Definition: data1.h:64
struct data1_node * child
Definition: data1.h:341
data1_node * data1_categoryList
Definition: zinfo.c:93
void zebraExplain_close(ZebraExplainInfo zei)
Definition: zinfo.c:208
int zebraExplain_ord_adjust_occurrences(ZebraExplainInfo zei, int ord, int term_delta, int doc_delta)
Definition: zinfo.c:1436
void zebra_exit(const char *msg)
Definition: exit.c:26
data1_attset_child * children
Definition: data1.h:73
void * handle
Definition: zinfo.c:50
data1_node * data1_mk_tag_data_int(data1_handle dh, data1_node *at, const char *tag, int num, NMEM nmem)
Definition: d1_read.c:473
int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
Definition: zinfo.c:791
Odr_oid * oid
Definition: zinfo.c:52
static void zebraExplain_updateAccessInfo(ZebraExplainInfo zei, data1_node *n, zebAccessInfo accessInfo)
Definition: zinfo.c:856
data1_handle dh
Definition: zinfo.c:103
char * data1_nodetoidsgml(data1_handle dh, data1_node *n, int select, int *len)
Definition: d1_write.c:230
zebAccessInfo accessInfo
Definition: zinfo.c:81
zint recordBytes
Definition: zinfo.c:76
#define STRCASECMP
Definition: zinfo.h:32
int which
Definition: data1.h:285
Record rec_new(Records p)
creates new record (to be written to file storage)
Definition: records.c:990
zinfo_index_category_t
Definition: zinfo.h:37
zint term_occurrences
Definition: zinfo.c:40
int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord, const char **index_type, const char **db, const char **string_index)
Definition: zinfo.c:1479
static void att_loadset(void *p, const char *n, const char *name)
Definition: zinfo.c:1614
zebAccessInfo accessInfo
Definition: zinfo.c:111
static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei, zebAttributeDetails zad, const char *databaseName, int key_flush)
Definition: zinfo.c:1044
zint sysno
Definition: recindex.h:32
zint runNumber
Definition: zinfo.h:108
zinfo_index_category_t cat
Definition: zinfo.c:36
int zebraExplain_get_database_ord(ZebraExplainInfo zei)
Definition: zinfo.c:1621
long zint
Zebra integer.
Definition: util.h:66
zint sysno
Definition: zinfo.c:51
struct data1_node * next
Definition: data1.h:340
void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n, zebAccessInfo *accessInfo)
Definition: zinfo.c:259
char * data
Definition: data1.h:307
struct zebSUInfoB * zebraExplain_add_sui_info(ZebraExplainInfo zei, zinfo_index_category_t cat, const char *index_type)
Definition: zinfo.c:1526
data1_attset_child * next
Definition: data1.h:65
data1_node * data1_target
Definition: zinfo.c:107
static void zebraExplain_readDatabase(ZebraExplainInfo zei, struct zebDatabaseInfoB *zdi)
Definition: zinfo.c:707
char * name
Definition: data1.h:58
struct zebraCategoryListInfo * categoryList
Definition: zinfo.c:108
data1_node * data1_mk_tag_data_text_uni(data1_handle dh, data1_node *at, const char *tag, const char *str, NMEM nmem)
Definition: d1_read.c:522
zebAccessObject next
Definition: zinfo.c:53
struct zebSUInfoB * zebraExplain_get_sui_info(ZebraExplainInfo zei, int ord, int dirty_mark, const char **db)
Definition: zinfo.c:1400
data1_attset * data1_get_attset(data1_handle dh, const char *name)
Definition: d1_absyn.c:288
RecordAttr * rec_init_attr(ZebraExplainInfo zei, Record rec)
Definition: zinfo.c:1595
ZEBRA_RES rec_put(Records p, Record *recpp)
puts record (writes into file storage)
Definition: records.c:1022
int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle, int(*f)(void *handle, int ord, const char *index_type, const char *string_index, zinfo_index_category_t cat))
Definition: zinfo.c:1381
Record rec_get_root(Records p)
gets root record
Definition: records.c:937
void zebraExplain_recordCountIncrement(ZebraExplainInfo zei, int adjust_num)
Definition: zinfo.c:1575
data1_node * data1_search_tag(data1_handle dh, data1_node *n, const char *tag)
Definition: d1_read.c:300
char * databaseName
Definition: zinfo.c:73
struct data1_handle_info * data1_handle
Definition: data1.h:77
#define DATA1N_data
Definition: data1.h:278
struct zebDatabaseInfoB * curDatabaseInfo
Definition: zinfo.c:110
char * name
Definition: zinfo.c:85
ZebraExplainUpdateFunc * updateFunc
Definition: zinfo.c:113
ZEBRA_RES rec_del(Records p, Record *recpp)
marks record for deletion (on file storage)
Definition: records.c:1000
data1_node * data1_tree
Definition: zinfo.c:67
zint recordCount
Definition: zinfo.c:75
#define ZINT_FORMAT
Definition: util.h:72