Happy new year
[idzebra-moved-to-github.git] / index / zebraapi.c
index 1cb58e6..539794d 100644 (file)
@@ -1,8 +1,5 @@
-/* $Id: zebraapi.c,v 1.268 2007-12-18 13:55:28 adam Exp $
-   Copyright (C) 1995-2007
-   Index Data ApS
-
-This file is part of the Zebra server.
+/* This file is part of the Zebra server.
+   Copyright (C) 1994-2009 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
@@ -426,6 +423,10 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
            if (zebra_maps_read_file(reg->zebra_maps, index_fname) != ZEBRA_OK)
                ret = ZEBRA_FAIL;
        }
+        else
+        {
+            zebra_maps_define_default_sort(reg->zebra_maps);
+        }
     }
 
     if (!(reg->records = rec_open(reg->bfs, rw, record_compression)))
@@ -448,6 +449,8 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name,
         sort_type = ZEBRA_SORT_TYPE_FLAT;
     else if (res_get_match(res, "sortindex", "i", "f"))
         sort_type = ZEBRA_SORT_TYPE_ISAMB;
+    else if (res_get_match(res, "sortindex", "m", "f"))
+        sort_type = ZEBRA_SORT_TYPE_MULTI;
     else
     {
        yaz_log(YLOG_WARN, "bad_value for 'sortindex'");
@@ -1124,11 +1127,18 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
     }
     else
     {
-       for (i = 0; i<num_recs; i++)
+        WRBUF addinfo_w = wrbuf_alloc();
+       for (i = 0; i < num_recs; i++)
        {
+            recs[i].errCode = 0;
+            recs[i].errString = 0;
+            recs[i].format = 0;
+            recs[i].len = 0;
+            recs[i].buf = 0;
+            recs[i].base = 0;
+            recs[i].sysno = poset[i].sysno;
            if (poset[i].term)
            {
-               recs[i].errCode = 0;
                recs[i].format = yaz_oid_recsyn_sutrs;
                recs[i].len = strlen(poset[i].term);
                recs[i].buf = poset[i].term;
@@ -1146,13 +1156,17 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
                zebra_snippets_hit_vector(zh, setname, poset[i].sysno, 
                                          hit_snippet);
 #endif
+                wrbuf_rewind(addinfo_w);
                recs[i].errCode =
                    zebra_record_fetch(zh, setname,
                                        poset[i].sysno, poset[i].score,
                                       stream, input_format, comp,
                                       &recs[i].format, &buf, &len,
-                                      &recs[i].base, &recs[i].errString);
+                                      &recs[i].base, addinfo_w);
                
+                if (wrbuf_len(addinfo_w))
+                    recs[i].errString =
+                        odr_strdup(stream, wrbuf_cstr(addinfo_w));
                recs[i].len = len;
                if (len > 0)
                {
@@ -1162,7 +1176,6 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
                else
                    recs[i].buf = buf;
                 recs[i].score = poset[i].score;
-                recs[i].sysno = poset[i].sysno;
                zebra_snippets_destroy(hit_snippet);
            }
            else
@@ -1176,14 +1189,10 @@ ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream,
                    ret = ZEBRA_FAIL;
                    break;
                }
-               recs[i].buf = 0;  /* no record and no error issued */
-               recs[i].len = 0;
-               recs[i].errCode = 0;
-               recs[i].format = 0;
-               recs[i].sysno = 0;
            }
        }
        zebra_meta_records_destroy(zh, poset, num_recs);
+        wrbuf_destroy(addinfo_w);
     }
     zebra_end_read(zh);
     xfree(pos_array);
@@ -1418,7 +1427,6 @@ int delete_w_handle(const char *info, void *handle)
 {
     ZebraHandle zh = (ZebraHandle) handle;
     ISAM_P pos;
-    ASSERTZH;
 
     if (*info == sizeof(pos))
     {
@@ -1428,18 +1436,52 @@ int delete_w_handle(const char *info, void *handle)
     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;
 }
 
@@ -1929,22 +1971,33 @@ ZEBRA_RES zebra_end_transaction(ZebraHandle zh, ZebraTransactionStatus *status)
 
 ZEBRA_RES zebra_repository_update(ZebraHandle zh, const char *path)
 {
-    ASSERTZH;
-    assert(path);
-    yaz_log(log_level, "updating %s", path);
-
-    if (zh->m_record_id && !strcmp(zh->m_record_id, "file"))
-        return zebra_update_file_match(zh, path);
-    else
-        return zebra_update_from_path(zh, path);
+    return zebra_repository_index(zh, path, action_update);
 }
 
 ZEBRA_RES zebra_repository_delete(ZebraHandle zh, const char *path)
 {
+    return zebra_repository_index(zh, path, action_delete);
+}
+
+ZEBRA_RES zebra_repository_index(ZebraHandle zh, const char *path,
+                                 enum zebra_recctrl_action_t action)
+{
     ASSERTZH;
     assert(path);
-    yaz_log(log_level, "deleting %s", path);
-    return zebra_delete_from_path(zh, path);
+
+    if (action == action_update)
+        yaz_log(log_level, "updating %s", path);
+    else if (action == action_delete)
+        yaz_log(log_level, "deleting %s", path);
+    else if (action == action_a_delete)
+        yaz_log(log_level, "attempt deleting %s", path);
+    else
+        yaz_log(log_level, "update action=%d", (int) action);
+
+    if (zh->m_record_id && !strcmp(zh->m_record_id, "file"))
+        return zebra_update_file_match(zh, path);
+    else
+        return zebra_update_from_path(zh, path, action);
 }
 
 ZEBRA_RES zebra_repository_show(ZebraHandle zh, const char *path)
@@ -2248,7 +2301,6 @@ ZEBRA_RES zebra_update_record(ZebraHandle zh,
        return ZEBRA_FAIL;
     res = zebra_buffer_extract_record(zh, buf, buf_size, 
                                       action,
-                                      0, /* test_mode */
                                       recordType,
                                       sysno,   
                                       match,