ZOOM: save record schema per request; fix caching
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 19 Aug 2013 14:10:47 +0000 (16:10 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 19 Aug 2013 14:10:47 +0000 (16:10 +0200)
This also fixes YAZ-671

src/zoom-c.c
src/zoom-p.h
src/zoom-record-cache.c
src/zoom-sru.c
src/zoom-z3950.c

index 7ac0304..03e6fe3 100644 (file)
@@ -199,11 +199,13 @@ void ZOOM_connection_remove_task(ZOOM_connection c)
             resultset_destroy(task->u.search.resultset);
             xfree(task->u.search.syntax);
             xfree(task->u.search.elementSetName);
+            xfree(task->u.search.schema);
             break;
         case ZOOM_TASK_RETRIEVE:
             resultset_destroy(task->u.retrieve.resultset);
             xfree(task->u.retrieve.syntax);
             xfree(task->u.retrieve.elementSetName);
+            xfree(task->u.retrieve.schema);
             break;
         case ZOOM_TASK_CONNECT:
             break;
@@ -679,7 +681,6 @@ ZOOM_resultset ZOOM_resultset_create(void)
     r->odr = odr_createmem(ODR_ENCODE);
     r->piggyback = 1;
     r->setname = 0;
-    r->schema = 0;
     r->step = 0;
     for (i = 0; i<RECORD_HASH_SIZE; i++)
         r->record_hash[i] = 0;
@@ -723,7 +724,7 @@ ZOOM_API(ZOOM_resultset)
     ZOOM_task task;
     const char *cp;
     int start, count;
-    const char *syntax, *elementSetName;
+    const char *syntax, *elementSetName, *schema;
 #if ZOOM_RESULT_LISTS
     ZOOM_resultsets set;
 #endif
@@ -746,9 +747,6 @@ ZOOM_API(ZOOM_resultset)
     cp = ZOOM_options_get(r->options, "setname");
     if (cp)
         r->setname = xstrdup(cp);
-    cp = ZOOM_options_get(r->options, "schema");
-    if (cp)
-        r->schema = xstrdup(cp);
 
     r->databaseNames = ZOOM_connection_get_databases(c, c->options, &r->num_databaseNames,
                                          r->odr);
@@ -789,8 +787,10 @@ ZOOM_API(ZOOM_resultset)
     syntax = ZOOM_options_get(r->options, "preferredRecordSyntax");
     task->u.search.syntax = syntax ? xstrdup(syntax) : 0;
     elementSetName = ZOOM_options_get(r->options, "elementSetName");
-    task->u.search.elementSetName = elementSetName
-        ? xstrdup(elementSetName) : 0;
+    task->u.search.elementSetName = elementSetName ?
+        xstrdup(elementSetName) : 0;
+    schema = ZOOM_options_get(r->options, "schema");
+    task->u.search.schema = schema ? xstrdup(schema) : 0;
 
     ZOOM_resultset_addref(r);
 
@@ -884,7 +884,6 @@ static void resultset_destroy(ZOOM_resultset r)
         ZOOM_options_destroy(r->options);
         odr_destroy(r->odr);
         xfree(r->setname);
-        xfree(r->schema);
         yaz_mutex_destroy(&r->mutex);
 #if SHPTR
         YAZ_SHPTR_DEC(r->record_wrbuf, wrbuf_destroy);
@@ -961,14 +960,7 @@ static void ZOOM_resultset_retrieve(ZOOM_resultset r,
         ? xstrdup(elementSetName) : 0;
 
     cp = ZOOM_options_get(r->options, "schema");
-    if (cp)
-    {
-        if (!r->schema || strcmp(r->schema, cp))
-        {
-            xfree(r->schema);
-            r->schema = xstrdup(cp);
-        }
-    }
+    task->u.retrieve.schema = cp ? xstrdup(cp) : 0;
 
     ZOOM_resultset_addref(r);
 
@@ -1146,8 +1138,10 @@ ZOOM_API(ZOOM_record)
         ZOOM_options_get(s->options, "preferredRecordSyntax");
     const char *elementSetName =
         ZOOM_options_get(s->options, "elementSetName");
+    const char *schema =
+        ZOOM_options_get(s->options, "schema");
 
-    return ZOOM_record_cache_lookup(s, pos, syntax, elementSetName);
+    return ZOOM_record_cache_lookup(s, pos, syntax, elementSetName, schema);
 }
 
 ZOOM_API(ZOOM_record)
index b205905..0f53b04 100644 (file)
@@ -135,7 +135,6 @@ struct ZOOM_resultset_p {
     int step;
     int piggyback;
     char *setname;
-    char *schema;
     ODR odr;
     ZOOM_record_cache record_hash[RECORD_HASH_SIZE];
     ZOOM_options options;
@@ -199,6 +198,7 @@ struct ZOOM_task_p {
             ZOOM_resultset resultset;
             char *syntax;
             char *elementSetName;
+            char *schema;
             int recv_search_fired;
         } search;
 #define ZOOM_TASK_RETRIEVE 2
@@ -208,6 +208,7 @@ struct ZOOM_task_p {
             int count;
             char *syntax;
             char *elementSetName;
+            char *schema;
         } retrieve;
 #define ZOOM_TASK_CONNECT 3
 #define ZOOM_TASK_SCAN 4
@@ -258,7 +259,8 @@ int ZOOM_test_reconnect(ZOOM_connection c);
 
 ZOOM_record ZOOM_record_cache_lookup(ZOOM_resultset r, int pos,
                                      const char *syntax,
-                                     const char *elementSetName);
+                                     const char *elementSetName,
+                                     const char *schema);
 void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
                            int pos,
                            const char *syntax, const char *elementSetName,
index 0b22b33..ea21312 100644 (file)
@@ -70,7 +70,7 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
     for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next)
     {
         if (pos == rc->pos
-            && yaz_strcmp_null(r->schema, rc->schema) == 0
+            && yaz_strcmp_null(schema, rc->schema) == 0
             && yaz_strcmp_null(elementSetName,rc->elementSetName) == 0
             && yaz_strcmp_null(syntax, rc->syntax) == 0)
             break;
@@ -89,7 +89,7 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
 
         rc->syntax = odr_strdup_null(r->odr, syntax);
 
-        rc->schema = odr_strdup_null(r->odr, r->schema);
+        rc->schema = odr_strdup_null(r->odr, schema);
 
         rc->pos = pos;
         rc->next = r->record_hash[record_hash(pos)];
@@ -118,7 +118,8 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
 
 ZOOM_record ZOOM_record_cache_lookup(ZOOM_resultset r, int pos,
                                      const char *syntax,
-                                     const char *elementSetName)
+                                     const char *elementSetName,
+                                     const char *schema)
 {
     ZOOM_record_cache rc;
 
@@ -126,7 +127,7 @@ ZOOM_record ZOOM_record_cache_lookup(ZOOM_resultset r, int pos,
     {
         if (pos == rc->pos)
         {
-            if (yaz_strcmp_null(r->schema, rc->schema))
+            if (yaz_strcmp_null(schema, rc->schema))
                 continue;
             if (yaz_strcmp_null(elementSetName,rc->elementSetName))
                 continue;
index 3e668a4..b997eeb 100644 (file)
@@ -130,6 +130,7 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
     ZOOM_resultset resultset = 0;
     Z_SRW_PDU *sr = 0;
     const char *option_val = 0;
+    const char *schema = 0;
     Z_Query *z_query;
     Z_FacetList *facet_list = 0;
     if (c->error)                  /* don't continue on error */
@@ -147,9 +148,11 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
         facets = ZOOM_options_get(resultset->options, "facets");
         if (facets)
             facet_list = yaz_pqf_parse_facet_list(c->odr_out, facets);
+        schema = c->tasks->u.search.schema;
         break;
     case ZOOM_TASK_RETRIEVE:
         resultset = c->tasks->u.retrieve.resultset;
+        schema = c->tasks->u.retrieve.schema;
 
         start = &c->tasks->u.retrieve.start;
         count = &c->tasks->u.retrieve.count;
@@ -164,7 +167,8 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
             ZOOM_record rec =
                 ZOOM_record_cache_lookup(resultset, i + *start,
                                          c->tasks->u.retrieve.syntax,
-                                         c->tasks->u.retrieve.elementSetName);
+                                         c->tasks->u.retrieve.elementSetName,
+                                         schema);
             if (!rec)
                 break;
             else
@@ -216,7 +220,7 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
     sr->u.request->maximumRecords = odr_intdup(
         c->odr_out, (resultset->step > 0 && resultset->step < *count) ?
         resultset->step : *count);
-    sr->u.request->recordSchema = resultset->schema;
+    sr->u.request->recordSchema = odr_strdup_null(c->odr_out, schema);
     sr->u.request->facetList = facet_list;
 
     option_val = ZOOM_resultset_option_get(resultset, "recordPacking");
index bea3125..fd605f5 100644 (file)
@@ -642,6 +642,7 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c)
     ZOOM_resultset r;
     int lslb, ssub, mspn;
     const char *syntax;
+    const char *schema;
     Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_searchRequest);
     Z_SearchRequest *search_req = apdu->u.searchRequest;
     const char *elementSetName;
@@ -722,6 +723,8 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c)
     /* get syntax (no need to provide unless piggyback is in effect) */
     syntax = c->tasks->u.search.syntax;
 
+    schema = c->tasks->u.search.schema;
+
     lslb = ZOOM_options_get_int(r->options, "largeSetLowerBound", -1);
     ssub = ZOOM_options_get_int(r->options, "smallSetUpperBound", -1);
     mspn = ZOOM_options_get_int(r->options, "mediumSetPresentNumber", -1);
@@ -733,7 +736,7 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c)
         *search_req->mediumSetPresentNumber = mspn;
     }
     else if (c->tasks->u.search.start == 0 && c->tasks->u.search.count > 0
-             && r->piggyback && !r->r_sort_spec && !r->schema)
+             && r->piggyback && !r->r_sort_spec && !schema)
     {
         /* Regular piggyback - do it unless we're going to do sort */
         *search_req->largeSetLowerBound = 2000000000;
@@ -1459,7 +1462,8 @@ zoom_ret send_Z3950_present(ZOOM_connection c)
     int i = 0;
     const char *syntax = 0;
     const char *elementSetName = 0;
-    ZOOM_resultset  resultset;
+    const char *schema = 0;
+    ZOOM_resultset resultset;
     int *start, *count;
 
     if (!c->tasks)
@@ -1476,6 +1480,7 @@ zoom_ret send_Z3950_present(ZOOM_connection c)
         count = &c->tasks->u.search.count;
         syntax = c->tasks->u.search.syntax;
         elementSetName = c->tasks->u.search.elementSetName;
+        schema =  c->tasks->u.search.schema;
         break;
     case ZOOM_TASK_RETRIEVE:
         resultset = c->tasks->u.retrieve.resultset;
@@ -1483,6 +1488,7 @@ zoom_ret send_Z3950_present(ZOOM_connection c)
         count = &c->tasks->u.retrieve.count;
         syntax = c->tasks->u.retrieve.syntax;
         elementSetName = c->tasks->u.retrieve.elementSetName;
+        schema = c->tasks->u.retrieve.schema;
         break;
     default:
         return zoom_complete;
@@ -1504,7 +1510,7 @@ zoom_ret send_Z3950_present(ZOOM_connection c)
     {
         ZOOM_record rec =
             ZOOM_record_cache_lookup(resultset, i + *start,
-                                     syntax, elementSetName);
+                                     syntax, elementSetName, schema);
         if (!rec)
             break;
         else
@@ -1543,7 +1549,7 @@ zoom_ret send_Z3950_present(ZOOM_connection c)
         req->preferredRecordSyntax =
             zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax);
 
-    if (resultset->schema && *resultset->schema)
+    if (schema && *schema)
     {
         Z_RecordComposition *compo = (Z_RecordComposition *)
             odr_malloc(c->odr_out, sizeof(*compo));
@@ -1561,14 +1567,14 @@ zoom_ret send_Z3950_present(ZOOM_connection c)
 
         compo->u.complex->generic->which = Z_Schema_oid;
         compo->u.complex->generic->schema.oid = (Odr_oid *)
-            zoom_yaz_str_to_z3950oid (c, CLASS_SCHEMA, resultset->schema);
+            zoom_yaz_str_to_z3950oid(c, CLASS_SCHEMA, schema);
 
         if (!compo->u.complex->generic->schema.oid)
         {
             /* OID wasn't a schema! Try record syntax instead. */
 
             compo->u.complex->generic->schema.oid = (Odr_oid *)
-                zoom_yaz_str_to_z3950oid (c, CLASS_RECSYN, resultset->schema);
+                zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, schema);
         }
         if (elementSetName && *elementSetName)
         {