Align Zebra API more so that ZEBRA_RES is used to signal error/OK.
[idzebra-moved-to-github.git] / index / zsets.c
index 9e95870..08a2cf4 100644 (file)
@@ -1,6 +1,6 @@
-/* $Id: zsets.c,v 1.76 2005-01-07 14:44:54 adam Exp $
+/* $Id: zsets.c,v 1.82 2005-05-11 12:39:37 adam Exp $
    Copyright (C) 1995-2005
-   Index Data Aps
+   Index Data ApS
 
 This file is part of the Zebra server.
 
@@ -30,6 +30,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #endif
 
 #include "index.h"
+#include <yaz/diagbib1.h>
 #include <rset.h>
 
 #define SORT_IDX_ENTRYSIZE 64
@@ -76,7 +77,7 @@ struct zset_sort_info {
 };
 
 static int log_level_set=0;
-static int log_level_sorting=0;
+static int log_level_sort=0;
 static int log_level_searchhits=0;
 static int log_level_searchterms=0;
 static int log_level_resultsets=0;
@@ -85,32 +86,78 @@ static void loglevels()
 {
     if (log_level_set)
         return;
-    log_level_sorting = yaz_log_module_level("sorting");
+    log_level_sort = yaz_log_module_level("sorting");
     log_level_searchhits = yaz_log_module_level("searchhits");
     log_level_searchterms = yaz_log_module_level("searchterms");
     log_level_resultsets = yaz_log_module_level("resultsets");
-    log_level_set=1;
+    log_level_set = 1;
 }
 
-ZebraSet resultSetAddRPN (ZebraHandle zh, NMEM m,
-                          Z_RPNQuery *rpn, int num_bases,
-                          char **basenames, 
-                          const char *setname)
+ZEBRA_RES resultSetSearch(ZebraHandle zh, NMEM nmem, NMEM rset_nmem,
+                         Z_RPNQuery *rpn, ZebraSet sset)
+{
+    RSET rset = 0;
+    oident *attrset;
+    Z_SortKeySpecList *sort_sequence;
+    int sort_status, i;
+    ZEBRA_RES res = ZEBRA_OK;
+
+    zh->hits = 0;
+
+    sort_sequence = (Z_SortKeySpecList *)
+        nmem_malloc(nmem, sizeof(*sort_sequence));
+    sort_sequence->num_specs = 10; /* FIXME - Hard-coded number */
+    sort_sequence->specs = (Z_SortKeySpec **)
+        nmem_malloc(nmem, sort_sequence->num_specs *
+                     sizeof(*sort_sequence->specs));
+    for (i = 0; i<sort_sequence->num_specs; i++)
+        sort_sequence->specs[i] = 0;
+    
+    attrset = oid_getentbyoid (rpn->attributeSetId);
+    res = rpn_search_top(zh, rpn->RPNStructure, attrset->value,
+                        nmem, rset_nmem,
+                        sort_sequence,
+                        sset->num_bases, sset->basenames,
+                        &rset);
+    if (res != ZEBRA_OK)
+    {
+       sset->rset = 0;
+        return res;
+    }
+    for (i = 0; sort_sequence->specs[i]; i++)
+        ;
+    sort_sequence->num_specs = i;
+    if (!i)
+    {
+        res = resultSetRank (zh, sset, rset, rset_nmem);
+    }
+    else
+    {
+        res = resultSetSortSingle (zh, nmem, sset, rset,
+                                  sort_sequence, &sort_status);
+    }
+    sset->rset = rset;
+    return res;
+}
+
+
+ZEBRA_RES resultSetAddRPN (ZebraHandle zh, NMEM m, Z_RPNQuery *rpn,
+                          int num_bases, char **basenames,
+                          const char *setname)
 {
     ZebraSet zebraSet;
     int i;
+    ZEBRA_RES res;
 
-    zh->errCode = 0;
-    zh->errString = NULL;
     zh->hits = 0;
 
     zebraSet = resultSetAdd (zh, setname, 1);
     if (!zebraSet)
-        return 0;
+        return ZEBRA_FAIL;
     zebraSet->locked = 1;
     zebraSet->rpn = 0;
     zebraSet->nmem = m;
-    zebraSet->rset_nmem=nmem_create(); 
+    zebraSet->rset_nmem = nmem_create(); 
 
     zebraSet->num_bases = num_bases;
     zebraSet->basenames = 
@@ -118,16 +165,15 @@ ZebraSet resultSetAddRPN (ZebraHandle zh, NMEM m,
     for (i = 0; i<num_bases; i++)
         zebraSet->basenames[i] = nmem_strdup (zebraSet->nmem, basenames[i]);
 
-
-    zebraSet->rset = rpn_search (zh, zebraSet->nmem, zebraSet->rset_nmem,
-                                 rpn, zebraSet->num_bases,
-                                 zebraSet->basenames, zebraSet->name,
-                                 zebraSet);
+    res = resultSetSearch(zh, zebraSet->nmem, zebraSet->rset_nmem,
+                         rpn, zebraSet);
     zh->hits = zebraSet->hits;
     if (zebraSet->rset)
         zebraSet->rpn = rpn;
     zebraSet->locked = 0;
-    return zebraSet;
+    if (!zebraSet->rset)
+       return ZEBRA_FAIL;
+    return res;
 }
 
 void resultSetAddTerm (ZebraHandle zh, ZebraSet s, int reg_type,
@@ -215,7 +261,7 @@ ZebraSet resultSetAdd (ZebraHandle zh, const char *name, int ov)
     s->term_entries = 0;
     s->hits = 0;
     s->rset = 0;
-    s->rset_nmem=0;
+    s->rset_nmem = 0;
     s->nmem = 0;
     s->rpn = 0;
     s->cache_position = 0;
@@ -236,9 +282,7 @@ ZebraSet resultSetGet (ZebraHandle zh, const char *name)
                 yaz_log(log_level_resultsets, "research %s", name);
                 if (!s->rset_nmem)
                     s->rset_nmem=nmem_create();
-                s->rset =
-                    rpn_search (zh, nmem, s->rset_nmem, s->rpn, s->num_bases,
-                                s->basenames, s->name, s);
+               resultSetSearch(zh, nmem, s->rset_nmem, s->rpn, s);
                 nmem_destroy (nmem);
             }
             return s;
@@ -276,8 +320,6 @@ void resultSetDestroy (ZebraHandle zh, int num, char **names,int *statuses)
     if (statuses)
         for (i = 0; i<num; i++)
             statuses[i] = Z_DeleteStatus_resultSetDidNotExist;
-    zh->errCode = 0;
-    zh->errString = NULL;
     while (*ss)
     {
         int i = -1;
@@ -396,7 +438,7 @@ ZebraMetaRecord *zebra_meta_records_create (ZebraHandle zh, const char *name,
                 position = positions[i];
                 if (position > 0 && position <= sort_info->num_entries)
                 {
-                    yaz_log(log_level_sorting, "got pos=" ZINT_FORMAT
+                    yaz_log(log_level_sort, "got pos=" ZINT_FORMAT
                            " (sorted)", position);
                     sr[i].sysno = sort_info->entries[position-1]->sysno;
                     sr[i].score = sort_info->entries[position-1]->score;
@@ -419,7 +461,7 @@ ZebraMetaRecord *zebra_meta_records_create (ZebraHandle zh, const char *name,
             
             if (sort_info)
                 position = sort_info->num_entries;
-            while (num_i < num && positions[num_i] < position)
+            while (num_i < num && positions[num_i] <= position)
                 num_i++;
            
            if (sset->cache_rfd &&
@@ -455,7 +497,7 @@ ZebraMetaRecord *zebra_meta_records_create (ZebraHandle zh, const char *name,
                     if (position == positions[num_i])
                     {
                         sr[num_i].sysno = psysno;
-                        yaz_log(log_level_sorting, "got pos=" ZINT_FORMAT " (unsorted)", position);
+                        yaz_log(log_level_sort, "got pos=" ZINT_FORMAT " (unsorted)", position);
                         sr[num_i].score = -1;
                         num_i++;
                     }
@@ -604,40 +646,40 @@ void resultSetInsertRank (ZebraHandle zh, struct zset_sort_info *sort_info,
     new_entry->score = score;
 }
 
-void resultSetSort (ZebraHandle zh, NMEM nmem,
-                    int num_input_setnames, const char **input_setnames,
-                    const char *output_setname,
-                    Z_SortKeySpecList *sort_sequence, int *sort_status)
+ZEBRA_RES resultSetSort(ZebraHandle zh, NMEM nmem,
+                       int num_input_setnames, const char **input_setnames,
+                       const char *output_setname,
+                       Z_SortKeySpecList *sort_sequence, int *sort_status)
 {
     ZebraSet sset;
     RSET rset;
 
     if (num_input_setnames == 0)
     {
-        zh->errCode = 208;
-        return ;
+       zebra_setError(zh, YAZ_BIB1_NO_RESULT_SET_NAME_SUPPLIED_ON_SORT, 0);
+       return ZEBRA_FAIL;
     }
     if (num_input_setnames > 1)
     {
-        zh->errCode = 230;
-        return;
+        zebra_setError(zh, YAZ_BIB1_SORT_TOO_MANY_INPUT_RESULTS, 0);
+       return ZEBRA_FAIL;
     }
     if (!log_level_set)
         loglevels();
-    yaz_log(log_level_sorting, "result set sort input=%s output=%s",
+    yaz_log(log_level_sort, "result set sort input=%s output=%s",
           *input_setnames, output_setname);
     sset = resultSetGet (zh, input_setnames[0]);
     if (!sset)
     {
-        zh->errCode = 30;
-        zh->errString = nmem_strdup (nmem, input_setnames[0]);
-        return;
+       zebra_setError(zh, YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
+                      input_setnames[0]);
+       return ZEBRA_FAIL;
     }
     if (!(rset = sset->rset))
     {
-        zh->errCode = 30;
-        zh->errString = nmem_strdup (nmem, input_setnames[0]);
-        return;
+       zebra_setError(zh, YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
+                      input_setnames[0]);
+       return ZEBRA_FAIL;
     }
     if (strcmp (output_setname, input_setnames[0]))
     {
@@ -645,12 +687,14 @@ void resultSetSort (ZebraHandle zh, NMEM nmem,
         sset = resultSetAdd (zh, output_setname, 1);
         sset->rset = rset;
     }
-    resultSetSortSingle (zh, nmem, sset, rset, sort_sequence, sort_status);
+    return resultSetSortSingle (zh, nmem, sset, rset, sort_sequence,
+                               sort_status);
 }
 
-void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
-                          ZebraSet sset, RSET rset,
-                          Z_SortKeySpecList *sort_sequence, int *sort_status)
+ZEBRA_RES resultSetSortSingle(ZebraHandle zh, NMEM nmem,
+                             ZebraSet sset, RSET rset,
+                             Z_SortKeySpecList *sort_sequence,
+                             int *sort_status)
 {
     int i;
     int n = 0;
@@ -686,53 +730,57 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
             sort_criteria[i].relation = 'D';
         else
         {
-            zh->errCode = 214;
-            return;
+           zebra_setError(zh, YAZ_BIB1_ILLEGAL_SORT_RELATION, 0);
+            return ZEBRA_FAIL;
         }
         if (sks->sortElement->which == Z_SortElement_databaseSpecific)
         {
-            zh->errCode = 210;
-            return;
+           zebra_setError(zh, YAZ_BIB1_DATABASE_SPECIFIC_SORT_UNSUPP, 0);
+            return ZEBRA_FAIL;
         }
         else if (sks->sortElement->which != Z_SortElement_generic)
         {
-            zh->errCode = 237;
-            return;
+           zebra_setError(zh, YAZ_BIB1_SORT_ILLEGAL_SORT, 0);
+            return ZEBRA_FAIL;
         }       
         sk = sks->sortElement->u.generic;
         switch (sk->which)
         {
         case Z_SortKey_sortField:
-            yaz_log(log_level_sorting, "Sort: key %d is of type sortField", i+1);
-            zh->errCode = 207;
-            return;
+            yaz_log(log_level_sort, "key %d is of type sortField",
+                   i+1);
+            zebra_setError(zh, YAZ_BIB1_CANNOT_SORT_ACCORDING_TO_SEQUENCE, 0);
+            return ZEBRA_FAIL;
         case Z_SortKey_elementSpec:
-            yaz_log(log_level_sorting, "Sort: key %d is of type elementSpec", i+1);
-            zh->errCode = 207;
-            return;
+            yaz_log(log_level_sort, "key %d is of type elementSpec",
+                   i+1);
+            zebra_setError(zh, YAZ_BIB1_CANNOT_SORT_ACCORDING_TO_SEQUENCE, 0);
+            return ZEBRA_FAIL;
         case Z_SortKey_sortAttributes:
-            yaz_log(log_level_sorting, "Sort: key %d is of type sortAttributes", i+1);
+            yaz_log(log_level_sort, "key %d is of type sortAttributes", i+1);
             sort_criteria[i].attrUse =
                 zebra_maps_sort (zh->reg->zebra_maps,
                                  sk->u.sortAttributes,
                                  &sort_criteria[i].numerical);
-            yaz_log(log_level_sorting, "use value = %d", sort_criteria[i].attrUse);
+            yaz_log(log_level_sort, "use value = %d", sort_criteria[i].attrUse);
             if (sort_criteria[i].attrUse == -1)
             {
-                zh->errCode = 116;
-                return;
+               zebra_setError(
+                   zh, YAZ_BIB1_USE_ATTRIBUTE_REQUIRED_BUT_NOT_SUPPLIED, 0); 
+                return ZEBRA_FAIL;
             }
             if (sortIdx_type (zh->reg->sortIdx, sort_criteria[i].attrUse))
             {
-                zh->errCode = 207;
-                return;
+               zebra_setError(
+                   zh, YAZ_BIB1_CANNOT_SORT_ACCORDING_TO_SEQUENCE, 0);
+                return ZEBRA_FAIL;
             }
             break;
         }
     }
     rfd = rset_open (rset, RSETF_READ);
+    /* FIXME - pass a TERMID *, and use it for something below !! */
     while (rset_read (rfd, &key, &termid))
-      /* FIXME - pass a TERMID *, and use it for something below !! */
     {
         zint this_sys = key.mem[0];
        kno++;
@@ -745,12 +793,13 @@ void resultSetSortSingle (ZebraHandle zh, NMEM nmem,
         }
     }
     rset_close (rfd);
-    yaz_log(log_level_sorting, ZINT_FORMAT " keys, " ZINT_FORMAT " sysnos, sort",
+    yaz_log(log_level_sort, ZINT_FORMAT " keys, " ZINT_FORMAT " sysnos, sort",
                    kno, sset->hits);   
     for (i = 0; i < numTerms; i++)
-        yaz_log(log_level_sorting, "term=\"%s\" type=%s count=" ZINT_FORMAT,
+        yaz_log(log_level_sort, "term=\"%s\" type=%s count=" ZINT_FORMAT,
                  terms[i]->name, terms[i]->flags, rset_count(terms[i]->rset));
     *sort_status = Z_SortResponse_success;
+    return ZEBRA_OK;
 }
 
 RSET resultSetRef (ZebraHandle zh, const char *resultSetId)
@@ -762,7 +811,8 @@ RSET resultSetRef (ZebraHandle zh, const char *resultSetId)
     return NULL;
 }
 
-void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset, NMEM nmem)
+ZEBRA_RES resultSetRank (ZebraHandle zh, ZebraSet zebraSet,
+                        RSET rset, NMEM nmem)
 {
     zint kno = 0;
     struct it_key key;
@@ -787,6 +837,7 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset, NMEM nmem)
     sort_info->num_entries = 0;
     zebraSet->hits = 0;
     rset_getterms(rset, 0, 0, &n);
+    yaz_log(YLOG_LOG, "Got %d terms", n);
     terms = (TERMID *) nmem_malloc(nmem, sizeof(*terms)*n);
     rset_getterms(rset, terms, n, &numTerms);
 
@@ -796,7 +847,8 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset, NMEM nmem)
     if (!rank_class)
     {
         yaz_log(YLOG_WARN, "No such rank handler: %s", rank_handler_name);
-        return;
+       zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, "Cannot find rank handler");
+        return ZEBRA_FAIL;
     }
     rc = rank_class->control;
 
@@ -825,7 +877,7 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset, NMEM nmem)
                 (zebraSet->hits)++;
                 psysno = this_sys;
             }
-            (*rc->add) (handle, seqno, termid);
+            (*rc->add) (handle, CAST_ZINT_TO_INT(seqno), termid);
             
             if ((est==-2) && (zebraSet->hits==esthits))
             { /* time to estimate the hits */
@@ -856,14 +908,16 @@ void resultSetRank (ZebraHandle zh, ZebraSet zebraSet, RSET rset, NMEM nmem)
         (*rc->end) (zh->reg, handle);
     }
     rset_close (rfd);
-
-    yaz_log(log_level_searchterms, ZINT_FORMAT " keys, " ZINT_FORMAT " sysnos, rank",
-           kno, zebraSet->hits);
+    
+    yaz_log(log_level_searchterms, ZINT_FORMAT " keys, "
+           ZINT_FORMAT " sysnos, rank",  kno, zebraSet->hits);
     for (i = 0; i < numTerms; i++)
     {
-        yaz_log(log_level_searchterms, "term=\"%s\" type=%s count=" ZINT_FORMAT,
-                 terms[i]->name, terms[i]->flags, rset_count(terms[i]->rset));
+        yaz_log(log_level_searchterms, "term=\"%s\" type=%s count="
+               ZINT_FORMAT,
+               terms[i]->name, terms[i]->flags, rset_count(terms[i]->rset));
     }
+    return ZEBRA_OK;
 }
 
 ZebraRankClass zebraRankLookup (ZebraHandle zh, const char *name)