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