Merge branch 'master' into bug_4688
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 8 Nov 2011 11:09:13 +0000 (12:09 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 8 Nov 2011 11:09:13 +0000 (12:09 +0100)
1  2 
src/client.c
src/session.h

diff --combined src/client.c
@@@ -121,7 -121,6 +121,7 @@@ struct client 
      YAZ_MUTEX mutex;
      int ref_count;
      char *id;
 +    facet_limits_t facet_limits;
  };
  
  struct suggestions {
@@@ -185,6 -184,8 +185,8 @@@ void client_set_state(struct client *cl
                  client_get_id(cl), no_active);
          if (no_active == 0) {
              session_alert_watch(cl->session, SESSION_WATCH_SHOW);
+             session_alert_watch(cl->session, SESSION_WATCH_BYTARGET);
+             session_alert_watch(cl->session, SESSION_WATCH_TERMLIST);
              session_alert_watch(cl->session, SESSION_WATCH_SHOW_PREF);
          }
      }
@@@ -555,57 -556,13 +557,59 @@@ void client_got_records(struct client *
      {
          client_unlock(cl);
          session_alert_watch(se, SESSION_WATCH_SHOW);
+         session_alert_watch(se, SESSION_WATCH_BYTARGET);
+         session_alert_watch(se, SESSION_WATCH_TERMLIST);
          session_alert_watch(se, SESSION_WATCH_RECORD);
          client_lock(cl);
      }
  }
  
 +static void client_record_ingest(struct client *cl)
 +{
 +    const char *msg, *addinfo;
 +    ZOOM_record rec = 0;
 +    ZOOM_resultset resultset = cl->resultset;
 +    int offset = cl->record_offset;
 +    if ((rec = ZOOM_resultset_record(resultset, offset)))
 +    {
 +        cl->record_offset++;
 +        if (cl->session == 0)
 +            ;
 +        else if (ZOOM_record_error(rec, &msg, &addinfo, 0))
 +        {
 +            yaz_log(YLOG_WARN, "Record error %s (%s): %s (rec #%d)",
 +                    msg, addinfo, client_get_id(cl),
 +                    cl->record_offset);
 +        }
 +        else
 +        {
 +            struct session_database *sdb = client_get_database(cl);
 +            NMEM nmem = nmem_create();
 +            const char *xmlrec;
 +            char type[80];
 +            
 +            if (nativesyntax_to_type(sdb, type, rec))
 +                yaz_log(YLOG_WARN, "Failed to determine record type");
 +            xmlrec = ZOOM_record_get(rec, type, NULL);
 +            if (!xmlrec)
 +                yaz_log(YLOG_WARN, "ZOOM_record_get failed from %s",
 +                        client_get_id(cl));
 +            else
 +            {
 +                /* OK = 0, -1 = failure, -2 = Filtered */
 +                if (ingest_record(cl, xmlrec, cl->record_offset, nmem) == -1)
 +                    yaz_log(YLOG_WARN, "Failed to ingest from %s", client_get_id(cl));
 +            }
 +            nmem_destroy(nmem);
 +        }
 +    }
 +    else
 +    {
 +        yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d",
 +                offset);
 +    }
 +}
 +
  void client_record_response(struct client *cl)
  {
      struct connection *co = cl->connection;
      }
      else
      {
 -        ZOOM_record rec = 0;
 -        const char *msg, *addinfo;
 -        
          if (cl->show_raw && cl->show_raw->active)
          {
 +            ZOOM_record rec = 0;
              if ((rec = ZOOM_resultset_record(resultset,
                                               cl->show_raw->position-1)))
              {
          }
          else
          {
 -            int offset = cl->record_offset;
 -            if ((rec = ZOOM_resultset_record(resultset, offset)))
 -            {
 -                cl->record_offset++;
 -                if (cl->session == 0)
 -                    ;
 -                else if (ZOOM_record_error(rec, &msg, &addinfo, 0))
 -                {
 -                    yaz_log(YLOG_WARN, "Record error %s (%s): %s (rec #%d)",
 -                            msg, addinfo, client_get_id(cl),
 -                            cl->record_offset);
 -                }
 -                else
 -                {
 -                    struct session_database *sdb = client_get_database(cl);
 -                    NMEM nmem = nmem_create();
 -                    const char *xmlrec;
 -                    char type[80];
 -
 -                    if (nativesyntax_to_type(sdb, type, rec))
 -                        yaz_log(YLOG_WARN, "Failed to determine record type");
 -                    xmlrec = ZOOM_record_get(rec, type, NULL);
 -                    if (!xmlrec)
 -                        yaz_log(YLOG_WARN, "ZOOM_record_get failed from %s",
 -                                client_get_id(cl));
 -                    else
 -                    {
 -                        /* OK = 0, -1 = failure, -2 = Filtered */
 -                        if (ingest_record(cl, xmlrec, cl->record_offset, nmem) == -1)
 -                            yaz_log(YLOG_WARN, "Failed to ingest from %s", client_get_id(cl));
 -                    }
 -                    nmem_destroy(nmem);
 -                }
 -            }
 -            else
 -            {
 -                yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d",
 -                        offset);
 -            }
 +            client_record_ingest(cl);
          }
      }
  }
  
 +void client_reingest(struct client *cl)
 +{
 +    int i = cl->startrecs;
 +    int to = cl->record_offset;
 +
 +    cl->record_offset = i;
 +    for (; i < to; i++)
 +        client_record_ingest(cl);
 +}
 +
  static void client_set_facets_request(struct client *cl, ZOOM_connection link)
  {
      struct session_database *sdb = client_get_database(cl);
@@@ -717,7 -704,6 +721,7 @@@ void client_start_search(struct client 
  
      assert(link);
  
 +    cl->hits = 0;
      cl->record_offset = 0;
      cl->diagnostic = 0;
  
@@@ -828,7 -814,6 +832,7 @@@ struct client *client_create(const cha
      pazpar2_mutex_create(&cl->mutex, "client");
      cl->preferred = 0;
      cl->ref_count = 1;
 +    cl->facet_limits = 0;
      assert(id);
      cl->id = xstrdup(id);
      client_use(1);
@@@ -867,7 -852,6 +871,7 @@@ int client_destroy(struct client *c
              c->cqlquery = 0;
              xfree(c->id);
              assert(!c->connection);
 +            facet_limits_destroy(c->facet_limits);
  
              if (c->resultset)
              {
@@@ -991,38 -975,10 +995,38 @@@ static char *make_solrquery(struct clie
      return r;
  }
  
 -static void apply_limit(struct session_database *sdb,
 -                        facet_limits_t facet_limits,
 -                        WRBUF w_pqf, WRBUF w_ccl)
 +const char *client_get_facet_limit_local(struct client *cl,
 +                                         struct session_database *sdb,
 +                                         int *l,
 +                                         NMEM nmem, int *num, char ***values)
  {
 +    const char *name = 0;
 +    const char *value = 0;
 +    for (; (name = facet_limits_get(cl->facet_limits, *l, &value)); (*l)++)
 +    {
 +        struct setting *s = 0;
 +        
 +        for (s = sdb->settings[PZ_LIMITMAP]; s; s = s->next)
 +        {
 +            const char *p = strchr(s->name + 3, ':');
 +            if (p && !strcmp(p + 1, name) && s->value &&
 +                !strncmp(s->value, "local:", 6))
 +            {
 +                nmem_strsplit_escape2(nmem, "|", value, values,
 +                                      num, 1, '\\', 1);
 +                (*l)++;
 +                return name;
 +            }
 +        }
 +    }
 +    return 0;
 +}
 +
 +static int apply_limit(struct session_database *sdb,
 +                       facet_limits_t facet_limits,
 +                       WRBUF w_pqf, WRBUF w_ccl)
 +{
 +    int ret = 0;
      int i = 0;
      const char *name;
      const char *value;
                      wrbuf_puts(w_ccl, ")");
  
                  }
 +                else if (!strncmp(s->value, "local:", 6))
 +                    ;
 +                else
 +                {
 +                    yaz_log(YLOG_WARN, "Target %s: Bad limitmap '%s'",
 +                            sdb->database->id, s->value);
 +                    ret = -1; /* bad limitmap */
 +                }
                  break;
              }
          }
          }
      }
      nmem_destroy(nmem_tmp);
 +    return ret;
  }
                          
  // Parse the query given the settings specific to this client
  int client_parse_query(struct client *cl, const char *query,
 -                       facet_limits_t facet_limits)
 +                       facet_limits_t facet_limits,
 +                       const char *startrecs, const char *maxrecs)
  {
      struct session *se = client_get_session(cl);
      struct session_database *sdb = client_get_database(cl);
      const char *pqf_strftime = session_setting_oneval(sdb, PZ_PQF_STRFTIME);
      const char *query_syntax = session_setting_oneval(sdb, PZ_QUERY_SYNTAX);
      WRBUF w_ccl, w_pqf;
 +    int ret_value = 1;
 +
      if (!ccl_map)
          return -1;
  
 -    cl->hits = -1;
 +
 +    if (maxrecs && atoi(maxrecs) != cl->maxrecs)
 +    {
 +        ret_value = 0;
 +        cl->maxrecs = atoi(maxrecs);
 +    }
 +
 +    if (startrecs && atoi(startrecs) != cl->startrecs)
 +    {
 +        ret_value = 0;
 +        cl->startrecs = atoi(startrecs);
 +    }
 +
      w_ccl = wrbuf_alloc();
      wrbuf_puts(w_ccl, query);
  
          wrbuf_puts(w_pqf, " ");
      }
  
 -    apply_limit(sdb, facet_limits, w_pqf, w_ccl);
 +    if (apply_limit(sdb, facet_limits, w_pqf, w_ccl))
 +        return -2;
 +
 +    facet_limits_destroy(cl->facet_limits);
 +    cl->facet_limits = facet_limits_dup(facet_limits);
  
      yaz_log(YLOG_LOG, "CCL query: %s", wrbuf_cstr(w_ccl));
      cn = ccl_find_str(ccl_map, wrbuf_cstr(w_ccl), &cerror, &cpos);
                  wrbuf_putc(w_pqf, cp[0]);
          }
      }
 -    xfree(cl->pquery);
 -    cl->pquery = xstrdup(wrbuf_cstr(w_pqf));
 +    if (!cl->pquery || strcmp(cl->pquery, wrbuf_cstr(w_pqf)))
 +    {
 +        xfree(cl->pquery);
 +        cl->pquery = xstrdup(wrbuf_cstr(w_pqf));
 +        ret_value = 0;
 +    }
      wrbuf_destroy(w_pqf);
  
      yaz_log(YLOG_LOG, "PQF query: %s", cl->pquery);
      }
  
      ccl_rpn_delete(cn);
 -    return 0;
 +    return ret_value;
  }
  
  void client_set_session(struct client *cl, struct session *se)
@@@ -1272,7 -1196,7 +1276,7 @@@ const char * client_get_suggestions_xml
      struct suggestions *suggestions = cl->suggestions;
  
      if (!suggestions) {
-         yaz_log(YLOG_DEBUG, "No suggestions found");
+         //yaz_log(YLOG_DEBUG, "No suggestions found");
          return "";
      }
      if (suggestions->passthrough) {
@@@ -1307,11 -1231,21 +1311,11 @@@ const char *client_get_id(struct clien
      return cl->id;
  }
  
 -void client_set_maxrecs(struct client *cl, int v)
 -{
 -    cl->maxrecs = v;
 -}
 -
  int client_get_maxrecs(struct client *cl)
  {
      return cl->maxrecs;
  }
  
 -void client_set_startrecs(struct client *cl, int v)
 -{
 -    cl->startrecs = v;
 -}
 -
  void client_set_preferred(struct client *cl, int v)
  {
      cl->preferred = v;
diff --combined src/session.h
@@@ -48,6 -48,7 +48,7 @@@ enum pazpar2_error_code 
      PAZPAR2_RECORD_FAIL,
      PAZPAR2_NOT_IMPLEMENTED,
      PAZPAR2_NO_SERVICE,
+     PAZPAR2_ALREADY_BLOCKED,
  
      PAZPAR2_LAST_ERROR
  };
@@@ -75,7 -76,9 +76,9 @@@ struct session_databas
  #define SESSION_WATCH_SHOW      0
  #define SESSION_WATCH_RECORD    1
  #define SESSION_WATCH_SHOW_PREF 2
- #define SESSION_WATCH_MAX       2
+ #define SESSION_WATCH_TERMLIST  3
+ #define SESSION_WATCH_BYTARGET  4
+ #define SESSION_WATCH_MAX       4
  
  #define SESSION_MAX_TERMLISTS 10
  
@@@ -99,8 -102,7 +102,8 @@@ struct client_list
  struct session {
      struct conf_service *service; /* service in use for this session */
      struct session_database *databases;  // All databases, settings overriden
 -    struct client_list *clients;   // Clients connected for current search
 +    struct client_list *clients_active; // Clients connected for current search
 +    struct client_list *clients_cached; // Clients in cache
      NMEM session_nmem;  // Nmem for session-permanent storage
      NMEM nmem;          // Nmem for each operation (i.e. search, result set, etc)
      int num_termlists;
      normalize_cache_t normalize_cache;
      YAZ_MUTEX session_mutex;
      unsigned session_id;
 +    int settings_modified;
      struct session_sorted_results *sorted_results;
  };