/* This file is part of the Zebra server.
- Copyright (C) 1995-2008 Index Data
+ Copyright (C) 1994-2011 Index Data
Zebra is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
*/
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#define ZEBRA_CHECK_HANDLE(zh) if (zebra_check_handle(zh) != ZEBRA_OK) return ZEBRA_FAIL
-static void zebra_chdir(ZebraService zs)
+static int zebra_chdir(ZebraService zs)
{
const char *dir ;
+ int r;
ASSERTZS;
yaz_log(log_level, "zebra_chdir");
dir = res_get(zs->global_res, "chdir");
if (!dir)
- return;
+ return 0;
yaz_log(YLOG_DEBUG, "chdir %s", dir);
#ifdef WIN32
- _chdir(dir);
+ r = _chdir(dir);
#else
- chdir(dir);
+ r = chdir(dir);
#endif
+ if (r)
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "chdir %s", dir);
+ return r;
}
static ZEBRA_RES zebra_flush_reg(ZebraHandle zh)
return ZEBRA_OK;
}
-static struct zebra_register *zebra_register_open(ZebraService zs,
+static struct zebra_register *zebra_register_open(ZebraService zs,
const char *name,
int rw, int useshadow,
Res res,
zh->destroyed = 0;
zh->errCode = 0;
zh->errString = 0;
- zh->res = 0;
+ zh->res = 0;
zh->session_res = res_open(zs->global_res, res);
zh->user_perm = 0;
zh->dbaccesslist = 0;
log_level = yaz_log_module_level("zebraapi");
log_level_initialized = 1;
}
-
+
+ *system_str = '\0';
+ *version_str = '\0';
zebra_get_version(version_str, system_str);
- yaz_log(YLOG_LOG, "zebra_start %s %s", version_str,
- configName ? configName : "");
+ yaz_log(YLOG_LOG, "zebra_start %s %s", version_str, system_str);
+ if (configName)
+ yaz_log(YLOG_LOG, "config %s", configName);
if ((res = res_open(def_res, over_res)))
{
zh = xmalloc(sizeof(*zh));
zh->global_res = res;
zh->sessions = 0;
-
- zebra_chdir(zh);
-
+
+ if (zebra_chdir(zh))
+ {
+ xfree(zh);
+ return 0;
+ }
+
zebra_mutex_cond_init(&zh->session_lock);
passwd_plain = res_get(zh->global_res, "passwd");
passwd_encrypt = res_get(zh->global_res, "passwd.c");
if (!passwd_plain && !passwd_encrypt)
zh->passwd_db = NULL;
- else
+ else
{
zh->passwd_db = passwd_db_open();
if (!zh->passwd_db)
{
struct zebra_register *reg;
int record_compression = REC_COMPRESS_NONE;
- const char *recordCompression = 0;
+ const char *compression_str = 0;
const char *profilePath;
- char cwd[1024];
int sort_type = ZEBRA_SORT_TYPE_FLAT;
ZEBRA_RES ret = ZEBRA_OK;
ASSERTZS;
-
+
reg = xmalloc(sizeof(*reg));
assert(name);
yaz_log(YLOG_DEBUG, "zebra_register_open rw=%d useshadow=%d p=%p n=%s rp=%s",
rw, useshadow, reg, name, reg_path ? reg_path : "(none)");
-
+
reg->dh = data1_create();
if (!reg->dh)
{
}
}
- getcwd(cwd, sizeof(cwd)-1);
profilePath = res_get_def(res, "profilePath", 0);
data1_set_tabpath(reg->dh, profilePath);
reg->isamc = 0;
reg->isamb = 0;
reg->zei = 0;
-
+
/* installing rank classes */
zebraRankInstall(reg, rank_1_class);
+ zebraRankInstall(reg, rank_2_class);
zebraRankInstall(reg, rank_similarity_class);
zebraRankInstall(reg, rank_static_class);
- recordCompression = res_get_def(res, "recordCompression", "none");
- if (!strcmp(recordCompression, "none"))
+ compression_str = res_get_def(res, "recordCompression", "none");
+ if (!strcmp(compression_str, "none"))
record_compression = REC_COMPRESS_NONE;
- if (!strcmp(recordCompression, "bzip2"))
+ else if (!strcmp(compression_str, "bzip2"))
record_compression = REC_COMPRESS_BZIP2;
+ else if (!strcmp(compression_str, "zlib"))
+ record_compression = REC_COMPRESS_ZLIB;
+ else
+ {
+ yaz_log(YLOG_FATAL, "invalid recordCompression: %s", compression_str);
+ ret = ZEBRA_FAIL;
+ }
+
+ if (!rec_check_compression_method(record_compression))
+ {
+ yaz_log(YLOG_FATAL, "unsupported recordCompression: %s",
+ compression_str);
+ ret = ZEBRA_FAIL;
+ }
{
const char *index_fname = res_get_def(res, "index", "default.idx");
ret = ZEBRA_FAIL;
}
-
+
if (res_get_match(res, "sortindex", "f", "f"))
sort_type = ZEBRA_SORT_TYPE_FLAT;
else if (res_get_match(res, "sortindex", "i", "f"))
if (res_get_match(res, "isam", "b", ISAM_DEFAULT))
{
struct ISAMC_M_s isamc_m;
-
+
if (!(reg->isamb = isamb_open(reg->bfs, "isamb",
rw, key_isamc_m(res, &isamc_m), 0)))
{
if (res_get_match(res, "isam", "bc", ISAM_DEFAULT))
{
struct ISAMC_M_s isamc_m;
-
+
if (!(reg->isamb = isamb_open(reg->bfs, "isamb",
rw, key_isamc_m(res, &isamc_m), 1)))
{
if (res_get_match(res, "isam", "null", ISAM_DEFAULT))
{
struct ISAMC_M_s isamc_m;
-
+
if (!(reg->isamb = isamb_open(reg->bfs, "isamb",
rw, key_isamc_m(res, &isamc_m), -1)))
{
ret = ZEBRA_FAIL;
}
}
-
+
if (ret != ZEBRA_OK)
{
zebra_register_close(zs, reg);
yaz_log(YLOG_DEBUG, "zebra_register_close p=%p", reg);
reg->stop_flag = 0;
zebra_chdir(zs);
-
+
zebraExplain_close(reg->zei);
dict_close(reg->dict);
if (reg->matchDict)
{
zebra_close(zs->sessions);
}
-
+
zebra_mutex_cond_destroy(&zs->session_lock);
if (zs->passwd_db)
yaz_timing_get_real(zs->timing),
yaz_timing_get_user(zs->timing),
yaz_timing_get_sys(zs->timing));
-
+
yaz_timing_destroy(&zs->timing);
xfree(zs);
ZEBRA_CHECK_HANDLE(zh);
zh->errCode = 0;
-
+
zs = zh->service;
yaz_log(YLOG_DEBUG, "zebra_close zh=%p", zh);
resultSetDestroy(zh, -1, 0, 0);
zh->path_reg = 0;
if (zh->service->path_root)
{
- zh->path_reg = xmalloc(strlen(zh->service->path_root) +
+ zh->path_reg = xmalloc(strlen(zh->service->path_root) +
strlen(zh->reg_name) + 3);
strcpy(zh->path_reg, zh->service->path_root);
if (*zh->reg_name)
}
}
zebra_open_res(zh);
-
+
if (zh->lock_normal)
zebra_lock_destroy(zh->lock_normal);
zh->lock_normal = 0;
{
char fname[512];
const char *lock_area = res_get(zh->res, "lockDir");
-
+
if (!lock_area && zh->path_reg)
res_set(zh->res, "lockDir", zh->path_reg);
sprintf(fname, "norm.%s.LCK", zh->reg_name);
zh->lock_normal =
zebra_lock_create(res_get(zh->res, "lockDir"), fname);
-
+
sprintf(fname, "shadow.%s.LCK", zh->reg_name);
zh->lock_shadow =
zebra_lock_create(res_get(zh->res, "lockDir"), fname);
}
if (zh->res)
{
- if (res_get_int(zh->res, "segment", &zh->m_segment_indexing) ==
+ if (res_get_int(zh->res, "segment", &zh->m_segment_indexing) ==
ZEBRA_OK)
{
yaz_log(YLOG_DEBUG, "segment indexing set and is %d",
assert(value);
assert(name);
assert(vp);
-
+
no =
sscanf(value, "%127s %127s %127s %127s %127s %127s %127s %127s %127s",
fromdb, todb[0], todb[1], todb[2], todb[3], todb[4],
{
if (p->new_num_bases == p->new_num_max)
return;
- p->new_basenames[(p->new_num_bases)++] =
+ p->new_basenames[(p->new_num_bases)++] =
nmem_strdup(p->mem, todb[i]);
}
return;
info.mem = stream->mem;
res_trav(zh->session_res, "mapdb", &info, map_basenames_func);
-
+
for (i = 0; i<p->num_bases; i++)
if (p->basenames[i] && p->new_num_bases < p->new_num_max)
{
- p->new_basenames[(p->new_num_bases)++] =
+ p->new_basenames[(p->new_num_bases)++] =
nmem_strdup(p->mem, p->basenames[i]);
}
*num_bases = info.new_num_bases;
yaz_log(log_level, "zebra_select_databases n=%d [0]=%s",
num_bases,basenames[0]);
zh->errCode = 0;
-
+
if (num_bases < 1)
{
zh->errCode = YAZ_BIB1_COMBI_OF_SPECIFIED_DATABASES_UNSUPP;
for (i = 0; i < zh->num_basenames; i++)
xfree(zh->basenames[i]);
xfree(zh->basenames);
-
+
zh->num_basenames = num_bases;
zh->basenames = xmalloc(zh->num_basenames * sizeof(*zh->basenames));
for (i = 0; i < zh->num_basenames; i++)
int *partial_resultset)
{
ZEBRA_RES r;
-
+
ZEBRA_CHECK_HANDLE(zh);
assert(o);
if (zebra_begin_read(zh) == ZEBRA_FAIL)
return ZEBRA_FAIL;
- r = resultSetAddRPN(zh, odr_extract_mem(o), query,
+ r = resultSetAddRPN(zh, odr_extract_mem(o), query,
zh->num_basenames, zh->basenames, setname,
hits, estimated_hit_count);
setname);
return ZEBRA_FAIL;
}
-
+
if (zebra_begin_read(zh) == ZEBRA_FAIL)
return ZEBRA_FAIL;
/* we disable hit snippets for now. It does not work well
and it slows retrieval down a lot */
#if 0
- zebra_snippets_hit_vector(zh, setname, poset[i].sysno,
+ zebra_snippets_hit_vector(zh, setname, poset[i].sysno,
hit_snippet);
#endif
wrbuf_rewind(addinfo_w);
stream, input_format, comp,
&recs[i].format, &buf, &len,
&recs[i].base, addinfo_w);
-
+
if (wrbuf_len(addinfo_w))
recs[i].errString =
odr_strdup(stream, wrbuf_cstr(addinfo_w));
Z_AttributesPlusTerm *zapt;
Odr_oid *attributeSet;
ZEBRA_RES res;
-
+
if (!(zapt = yaz_pqf_scan(pqf_parser, stream, &attributeSet, query)))
{
res = ZEBRA_FAIL;
return zh->errCode;
}
yaz_log(log_level, "zebra_errCode: o");
- return 0;
+ return 0;
}
const char *zebra_errString(ZebraHandle zh)
ZEBRA_CHECK_HANDLE(zh);
zs = zh->service;
-
+
sprintf(u, "perm.%.30s", user ? user : "anonymous");
p = res_get(zs->global_res, u);
xfree(zh->user_perm);
/* users that don't require a password .. */
if (zh->user_perm && strchr(zh->user_perm, 'a'))
return ZEBRA_OK;
-
+
if (!zs->passwd_db || !passwd_db_auth(zs->passwd_db, user, pass))
return ZEBRA_OK;
return ZEBRA_FAIL;
ZEBRA_RES zebra_admin_import_begin(ZebraHandle zh, const char *database,
const char *record_type)
{
- yaz_log(log_level, "zebra_admin_import_begin db=%s rt=%s",
+ yaz_log(log_level, "zebra_admin_import_begin db=%s rt=%s",
database, record_type);
if (zebra_select_database(zh, database) == ZEBRA_FAIL)
return ZEBRA_FAIL;
{
Odr_oct *oct = fragment->u.notExternallyTagged;
sysno = 0;
-
+
if(zebra_update_record(
- zh,
+ zh,
action_update,
0, /* record Type */
&sysno,
{
ZebraHandle zh = (ZebraHandle) handle;
ISAM_P pos;
- ASSERTZH;
if (*info == sizeof(pos))
{
return 0;
}
-static int delete_SU_handle(void *handle, int ord)
+int delete_w_all_handle(const char *info, void *handle)
+{
+ ZebraHandle zh = (ZebraHandle) handle;
+ ISAM_P pos;
+
+ if (*info == sizeof(pos))
+ {
+ ISAMB_PP pt;
+ memcpy(&pos, info+1, sizeof(pos));
+ pt = isamb_pp_open(zh->reg->isamb, pos, 2);
+ if (pt)
+ {
+ struct it_key key;
+ key.mem[0] = 0;
+ while (isamb_pp_read(pt, &key))
+ {
+ Record rec;
+ rec = rec_get(zh->reg->records, key.mem[0]);
+ rec_del(zh->reg->records, &rec);
+ }
+ isamb_pp_close(pt);
+ }
+ }
+ return delete_w_handle(info, handle);
+}
+
+static int delete_SU_handle(void *handle, int ord,
+ const char *index_type, const char *string_index,
+ zinfo_index_category_t cat)
{
ZebraHandle zh = (ZebraHandle) handle;
char ord_buf[20];
int ord_len;
-
+#if 0
+ yaz_log(YLOG_LOG, "ord=%d index_type=%s index=%s cat=%d", ord,
+ index_type, string_index, (int) cat);
+#endif
ord_len = key_SU_encode(ord, ord_buf);
ord_buf[ord_len] = '\0';
assert(zh->reg->isamb);
+ assert(zh->reg->records);
dict_delete_subtree(zh->reg->dict, ord_buf,
- zh, delete_w_handle);
+ zh,
+ !strcmp(string_index, "_ALLRECORDS") ?
+ delete_w_all_handle : delete_w_handle);
return 0;
}
return ZEBRA_FAIL;
/* announce database */
- if (zebraExplain_newDatabase(zh->reg->zei, db, 0
+ if (zebraExplain_newDatabase(zh->reg->zei, db, 0
/* explainDatabase */))
{
if (zebra_end_trans(zh) != ZEBRA_OK)
\param zh Zebra handle
\param val state
\param seqno sequence number
-
+
val is one of:
d=writing to shadow(shadow enabled); writing to register (shadow disabled)
o=reading only
sprintf(state_fname, "state.%s.LCK", zh->reg_name);
fname = zebra_mk_fname(res_get(zh->res, "lockDir"), state_fname);
f = fopen(fname, "w");
-
+ if (!f)
+ {
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s w", state_fname);
+ exit(1);
+ }
yaz_log(YLOG_DEBUG, "zebra_set_state: %c %d %ld", val, seqno, p);
fprintf(f, "%c %d %ld\n", val, seqno, p);
fclose(f);
if (f)
{
- fscanf(f, "%c %d", val, seqno);
+ if (fscanf(f, "%c %d", val, seqno) != 2)
+ {
+ yaz_log(YLOG_ERRNO|YLOG_WARN, "fscan fail %s",
+ state_fname);
+ }
fclose(f);
}
xfree(fname);
const char *group = res_get(zh->res, "group");
const char *v;
/* FIXME - do we still use groups ?? */
-
+
zh->m_group = group;
v = res_get_prefix(zh->res, "followLinks", group, "1");
zh->m_follow_links = atoi(v);
int seqno = 0;
char val = '?';
const char *rval = 0;
-
+
(zh->trans_no++);
if (zh->trans_w_no)
{
zh->records_deleted = 0;
zh->records_processed = 0;
zh->records_skipped = 0;
-
+
#if HAVE_SYS_TIMES_H
times(&zh->tms1);
#endif
/* lock */
if (zh->shadow_enable)
rval = res_get(zh->res, "shadow");
-
+
if (rval)
{
zebra_lock_r(zh->lock_normal);
}
zebra_set_state(zh, 'd', seqno);
-
+
zh->reg = zebra_register_open(zh->service, zh->reg_name,
1, rval ? 1 : 0, zh->res,
zh->path_reg);
- if (zh->reg)
- zh->reg->seqno = seqno;
- else
+ if (!zh->reg)
{
- zebra_set_state(zh, 'o', seqno);
-
zebra_unlock(zh->lock_shadow);
zebra_unlock(zh->lock_normal);
yaz_log(YLOG_FATAL, "%s", zh->errString);
return ZEBRA_FAIL;
}
+ zh->reg->seqno = seqno;
zebraExplain_curDatabase(zh->reg->zei, zh->basenames[0]);
}
else
int dirty = 0;
char val;
int seqno;
-
+
(zh->trans_no)++;
-
+
if (zh->trans_no != 1)
{
return zebra_flush_reg(zh);
zebra_get_state(zh, &val, &seqno);
if (val == 'd')
val = 'o';
-
+
if (!zh->reg)
dirty = 1;
else if (seqno != zh->reg->seqno)
}
if (!dirty)
return ZEBRA_OK;
-
+
if (val == 'c')
zebra_lock_r(zh->lock_shadow);
else
zebra_lock_r(zh->lock_normal);
-
+
if (zh->reg)
{
resultSetInvalidate(zh);
{ /* release write lock */
zh->trans_no--;
zh->trans_w_no = 0;
-
+
yaz_log(YLOG_DEBUG, "zebra_end_trans");
rval = res_get(zh->res, "shadow");
-
+
zebraExplain_runNumberIncrement(zh->reg->zei, 1);
-
+
zebra_flush_reg(zh);
-
+
resultSetInvalidate(zh);
zebra_register_close(zh->service, zh->reg);
zh->reg = 0;
-
+
yaz_log(YLOG_LOG, "Records: "ZINT_FORMAT" i/u/d "
- ZINT_FORMAT"/"ZINT_FORMAT"/"ZINT_FORMAT,
+ ZINT_FORMAT"/"ZINT_FORMAT"/"ZINT_FORMAT,
zh->records_processed, zh->records_inserted,
zh->records_updated, zh->records_deleted);
-
+
status->processed = zh->records_processed;
status->inserted = zh->records_inserted;
status->updated = zh->records_updated;
status->deleted = zh->records_deleted;
-
+
zebra_get_state(zh, &val, &seqno);
if (val != 'd')
{
zebra_set_state(zh, 'o', seqno);
zebra_unlock(zh->lock_shadow);
zebra_unlock(zh->lock_normal);
-
+
}
#if HAVE_SYS_TIMES_H
times(&zh->tms2);
yaz_log(log_level, "user/system: %ld/%ld",
(long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
(long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
-
+
status->utime = (long) (zh->tms2.tms_utime - zh->tms1.tms_utime);
status->stime = (long) (zh->tms2.tms_stime - zh->tms1.tms_stime);
#endif
zh->errCode = YAZ_BIB1_DATABASE_UNAVAILABLE;
return ZEBRA_FAIL;
}
- rval = res_get(zh->res, "shadow");
+ rval = res_get(zh->res, "shadow");
if (!rval)
{
yaz_log(YLOG_WARN, "Cannot perform commit - No shadow area defined");
else
{
zebra_set_state(zh, 'c', seqno);
-
+
yaz_log(log_level, "commit start");
if (bf_commitExec(bfs))
res = ZEBRA_FAIL;
{
seqno++;
zebra_set_state(zh, 'o', seqno);
-
+
zebra_unlock(zh->lock_shadow);
zebra_unlock(zh->lock_normal);
-
+
zebra_lock_w(zh->lock_shadow);
bf_commitClean(bfs, rval);
zebra_unlock(zh->lock_shadow);
}
if (rval && *rval)
bf_cache(bfs, rval);
-
+
bf_reset(bfs);
bfs_destroy(bfs);
zebra_set_state(zh, 'o', 0);
return ZEBRA_OK;
}
+#define ZEBRA_CHECK_DICT 1
+#define ZEBRA_CHECK_ISAM 2
+
+static ZEBRA_RES zebra_record_check(ZebraHandle zh, Record rec,
+ zint *no_keys, int message_limit,
+ unsigned flags,
+ zint *no_long_dict_entries,
+ zint *no_failed_dict_lookups,
+ zint *no_invalid_keys,
+ zint *no_invalid_dict_infos,
+ zint *no_invalid_isam_entries)
+{
+ ZEBRA_RES res = ZEBRA_OK;
+ zebra_rec_keys_t keys = zebra_rec_keys_open();
+ zebra_rec_keys_set_buf(keys, rec->info[recInfo_delKeys],
+ rec->size[recInfo_delKeys], 0);
+
+ *no_keys = 0;
+ if (!zebra_rec_keys_rewind(keys))
+ {
+ ;
+ }
+ else
+ {
+ size_t slen;
+ const char *str;
+ struct it_key key_in;
+ NMEM nmem = nmem_create();
+
+ while (zebra_rec_keys_read(keys, &str, &slen, &key_in))
+ {
+ int do_fail = 0;
+ int ord = CAST_ZINT_TO_INT(key_in.mem[0]);
+ char ord_buf[IT_MAX_WORD+20];
+ int ord_len = key_SU_encode(ord, ord_buf);
+ char *info = 0;
+
+ (*no_keys)++;
+
+ if (key_in.len < 2 || key_in.len > IT_KEY_LEVEL_MAX)
+ {
+ res = ZEBRA_FAIL;
+ (*no_invalid_keys)++;
+ if (*no_invalid_keys <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": unexpected key length %d",
+ rec->sysno, key_in.len);
+ }
+ }
+ if (ord_len + slen >= sizeof(ord_buf)-1)
+ {
+ res = ZEBRA_FAIL;
+ (*no_long_dict_entries)++;
+ if (*no_long_dict_entries <= message_limit)
+ {
+ do_fail = 1;
+ /* so bad it can not fit into our ord_buf */
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": long dictionary entry %d + %d",
+ rec->sysno, ord_len, (int) slen);
+ }
+ continue;
+ }
+ memcpy(ord_buf + ord_len, str, slen);
+ ord_buf[ord_len + slen] = '\0';
+ if (ord_len + slen >= IT_MAX_WORD)
+ {
+ res = ZEBRA_FAIL;
+ (*no_long_dict_entries)++;
+ if (*no_long_dict_entries <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": long dictionary entry %d + %d",
+ rec->sysno, (int) ord_len, (int) slen);
+ }
+ }
+ if ((flags & ZEBRA_CHECK_DICT) == 0)
+ continue;
+ info = dict_lookup(zh->reg->dict, ord_buf);
+ if (!info)
+ {
+ res = ZEBRA_FAIL;
+ (*no_failed_dict_lookups)++;
+ if (*no_failed_dict_lookups <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": term do not exist in dictionary", rec->sysno);
+ }
+ }
+ else if (flags & ZEBRA_CHECK_ISAM)
+ {
+ ISAM_P pos;
+
+ if (*info != sizeof(pos))
+ {
+ res = ZEBRA_FAIL;
+ (*no_invalid_dict_infos)++;
+ if (*no_invalid_dict_infos <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": long dictionary entry %d + %d",
+ rec->sysno, (int) ord_len, (int) slen);
+ }
+ }
+ else
+ {
+ int scope = 1;
+ memcpy(&pos, info+1, sizeof(pos));
+ if (zh->reg->isamb)
+ {
+ ISAMB_PP ispt = isamb_pp_open(zh->reg->isamb, pos,
+ scope);
+ if (!ispt)
+ {
+ res = ZEBRA_FAIL;
+ (*no_invalid_isam_entries)++;
+ if (*no_invalid_isam_entries <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": isamb_pp_open entry " ZINT_FORMAT
+ " not found",
+ rec->sysno, pos);
+ }
+ }
+ else if (zh->m_staticrank)
+ {
+ isamb_pp_close(ispt);
+ }
+ else
+ {
+ struct it_key until_key;
+ struct it_key isam_key;
+ int r;
+ int i = 0;
+
+ until_key.len = key_in.len - 1;
+ for (i = 0; i < until_key.len; i++)
+ until_key.mem[i] = key_in.mem[i+1];
+
+ if (until_key.mem[0] == 0)
+ until_key.mem[0] = rec->sysno;
+ r = isamb_pp_forward(ispt, &isam_key, &until_key);
+ if (r != 1)
+ {
+ res = ZEBRA_FAIL;
+ (*no_invalid_isam_entries)++;
+ if (*no_invalid_isam_entries <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record " ZINT_FORMAT
+ ": isamb_pp_forward " ZINT_FORMAT
+ " returned no entry",
+ rec->sysno, pos);
+ }
+ }
+ else
+ {
+ int cmp = key_compare(&until_key, &isam_key);
+ if (cmp != 0)
+ {
+ res = ZEBRA_FAIL;
+ (*no_invalid_isam_entries)++;
+ if (*no_invalid_isam_entries
+ <= message_limit)
+ {
+ do_fail = 1;
+ yaz_log(YLOG_WARN, "Record "
+ ZINT_FORMAT
+ ": isamb_pp_forward "
+ ZINT_FORMAT
+ " returned different entry",
+ rec->sysno, pos);
+
+ key_logdump_txt(YLOG_LOG,
+ &until_key,
+ "until");
+
+ key_logdump_txt(YLOG_LOG,
+ &isam_key,
+ "isam");
+
+ }
+ }
+ }
+ isamb_pp_close(ispt);
+ }
+
+ }
+ }
+ }
+ if (do_fail)
+ {
+ zebra_it_key_str_dump(zh, &key_in, str,
+ slen, nmem, YLOG_LOG);
+ nmem_reset(nmem);
+ }
+ }
+ nmem_destroy(nmem);
+ }
+ zebra_rec_keys_close(keys);
+ return res;
+}
+
+ZEBRA_RES zebra_register_check(ZebraHandle zh, const char *spec)
+{
+ ZEBRA_RES res = ZEBRA_FAIL;
+ unsigned flags = 0;
+ int message_limit = 10;
+
+ if (!spec || *spec == '\0'
+ || !strcmp(spec, "dict") || !strcmp(spec, "default"))
+ flags = ZEBRA_CHECK_DICT;
+ else if (!strcmp(spec, "isam") || !strcmp(spec, "full"))
+ flags = ZEBRA_CHECK_DICT|ZEBRA_CHECK_ISAM;
+ else if (!strcmp(spec, "quick"))
+ flags = 0;
+ else
+ return ZEBRA_FAIL;
+
+ yaz_log(YLOG_LOG, "zebra_register_check begin flags=%u message_limit=%d",
+ flags, message_limit);
+ if (zebra_begin_read(zh) == ZEBRA_OK)
+ {
+ zint no_records_total = 0;
+ zint no_records_fail = 0;
+ zint total_keys = 0;
+
+ if (zh->reg)
+ {
+ Record rec = rec_get_root(zh->reg->records);
+
+ zint no_long_dict_entries = 0;
+ zint no_failed_dict_lookups = 0;
+ zint no_invalid_keys = 0;
+ zint no_invalid_dict_infos = 0;
+ zint no_invalid_isam_entries = 0;
+
+ res = ZEBRA_OK;
+ while (rec)
+ {
+ Record r1;
+ zint no_keys;
+
+ if (zebra_record_check(zh, rec, &no_keys, message_limit,
+ flags,
+ &no_long_dict_entries,
+ &no_failed_dict_lookups,
+ &no_invalid_keys,
+ &no_invalid_dict_infos,
+ &no_invalid_isam_entries
+ )
+ != ZEBRA_OK)
+ {
+ res = ZEBRA_FAIL;
+ no_records_fail++;
+ }
+
+ r1 = rec_get_next(zh->reg->records, rec);
+ rec_free(&rec);
+ rec = r1;
+ no_records_total++;
+ total_keys += no_keys;
+ }
+ yaz_log(YLOG_LOG, "records total: " ZINT_FORMAT,
+ no_records_total);
+ yaz_log(YLOG_LOG, "records fail: " ZINT_FORMAT,
+ no_records_fail);
+ yaz_log(YLOG_LOG, "total keys: " ZINT_FORMAT,
+ total_keys);
+ yaz_log(YLOG_LOG, "long dict entries: " ZINT_FORMAT,
+ no_long_dict_entries);
+ if (flags & ZEBRA_CHECK_DICT)
+ {
+ yaz_log(YLOG_LOG, "failed dict lookups: " ZINT_FORMAT,
+ no_failed_dict_lookups);
+ yaz_log(YLOG_LOG, "invalid dict infos: " ZINT_FORMAT,
+ no_invalid_dict_infos);
+ }
+ if (flags & ZEBRA_CHECK_ISAM)
+ yaz_log(YLOG_LOG, "invalid isam entries: " ZINT_FORMAT,
+ no_invalid_isam_entries);
+ }
+ zebra_end_read(zh);
+ }
+ yaz_log(YLOG_LOG, "zebra_register_check end ret=%d", res);
+ return res;
+}
+
void zebra_result(ZebraHandle zh, int *code, char **addinfo)
{
yaz_log(log_level, "zebra_result");
yaz_iconv_close(zh->iconv_to_utf8);
if (zh->iconv_from_utf8 != 0)
yaz_iconv_close(zh->iconv_from_utf8);
-
+
zh->iconv_to_utf8 =
yaz_iconv_open("UTF-8", encoding);
if (zh->iconv_to_utf8 == 0)
ZEBRA_RES zebra_add_record(ZebraHandle zh,
const char *buf, int buf_size)
{
- return zebra_update_record(zh, action_update,
+ return zebra_update_record(zh, action_update,
0 /* record type */,
0 /* sysno */ ,
- 0 /* match */,
+ 0 /* match */,
0 /* fname */,
buf, buf_size);
}
-ZEBRA_RES zebra_update_record(ZebraHandle zh,
+ZEBRA_RES zebra_update_record(ZebraHandle zh,
enum zebra_recctrl_action_t action,
const char *recordType,
zint *sysno, const char *match,
if (zebra_begin_trans(zh, 1) == ZEBRA_FAIL)
return ZEBRA_FAIL;
- res = zebra_buffer_extract_record(zh, buf, buf_size,
+ res = zebra_buffer_extract_record(zh, buf, buf_size,
action,
- 0, /* test_mode */
recordType,
- sysno,
- match,
+ sysno,
+ match,
fname);
if (zebra_end_trans(zh) != ZEBRA_OK)
{
yaz_log(YLOG_WARN, "zebra_end_trans failed");
res = ZEBRA_FAIL;
}
- return res;
+ return res;
}
/* ---------------------------------------------------------------------------
- Searching
+ Searching
*/
ZEBRA_RES zebra_search_PQF(ZebraHandle zh, const char *pqf_query,
assert(setname);
yaz_log(log_level, "zebra_search_PQF s=%s q=%s", setname, pqf_query);
-
+
query = p_query_rpn(odr, pqf_query);
-
+
if (!query)
{
yaz_log(YLOG_WARN, "bad query %s\n", pqf_query);
}
else
res = zebra_search_RPN(zh, odr, query, setname, &lhits);
-
+
odr_destroy(odr);
yaz_log(log_level, "Hits: " ZINT_FORMAT, lhits);
int zebra_sort_by_specstr(ZebraHandle zh, ODR stream,
const char *sort_spec,
const char *output_setname,
- const char **input_setnames)
+ const char **input_setnames)
{
int num_input_setnames = 0;
int sort_status = 0;
zh->errCode = YAZ_BIB1_CANNOT_SORT_ACCORDING_TO_SEQUENCE;
return -1;
}
-
- /* we can do this, since the perl typemap code for char** will
+
+ /* we can do this, since the perl typemap code for char** will
put a NULL at the end of list */
while (input_setnames[num_input_setnames]) num_input_setnames++;
if (zebra_begin_read(zh))
return -1;
-
+
resultSetSort(zh, stream->mem, num_input_setnames, input_setnames,
output_setname, sort_sequence, &sort_status);
-
+
zebra_end_read(zh);
return sort_status;
}
void zebra_lock_prefix(Res res, char *path)
{
const char *lock_dir = res_get_def(res, "lockDir", "");
-
+
strcpy(path, lock_dir);
if (*path && path[strlen(path)-1] != '/')
strcat(path, "/");
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab