progressing slowly
[metaproxy-moved-to-github.git] / src / filter_record_transform.cpp
index 6201697..b223d26 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: filter_record_transform.cpp,v 1.2 2006-10-04 11:21:47 marc Exp $
+/* $Id: filter_record_transform.cpp,v 1.5 2006-10-05 20:19:50 marc Exp $
    Copyright (c) 2005-2006, Index Data.
 
    See the LICENSE file for details
@@ -21,6 +21,7 @@
 
 namespace mp = metaproxy_1;
 namespace yf = mp::filter;
+namespace mp_util = metaproxy_1::util;
 
 namespace metaproxy_1 {
     namespace filter {
@@ -117,39 +118,162 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const
     }
     
     // getting original present request
-    Z_PresentRequest *pr = gdu_req->u.z3950->u.presentRequest;
+    Z_PresentRequest *pr_req = gdu_req->u.z3950->u.presentRequest;
 
     // setting up ODR's for memory during encoding/decoding
     //mp::odr odr_de(ODR_DECODE);  
     mp::odr odr_en(ODR_ENCODE);
 
-    // now re-insructing the z3950 backend present request
+    // setting up variables for conversion state
+    yaz_record_conv_t rc = 0;
+    int ret_code;
+
+    const char *input_schema = 0;
+    Odr_oid *input_syntax = 0;
+
+    if(pr_req->recordComposition){
+        input_schema 
+            = mp_util::record_composition_to_esn(pr_req->recordComposition);
+    }
+    if(pr_req->preferredRecordSyntax){
+        input_syntax = pr_req->preferredRecordSyntax;
+    }
+    
+    const char *match_schema = 0;
+    int *match_syntax = 0;
+
+    const char *backend_schema = 0;
+    Odr_oid *backend_syntax = 0;
+
+    ret_code 
+        = yaz_retrieval_request(m_retrieval,
+                                input_schema, input_syntax,
+                                &match_schema, &match_syntax,
+                                &rc,
+                                &backend_schema, &backend_syntax);
+
+    // debug output - to be removed later
+    std::cout << "ret_code " <<  ret_code << "\n";
+    std::cout << "input   " << input_syntax << " ";
+    if (input_syntax)
+        std::cout << (oid_getentbyoid(input_syntax))->desc << " ";
+    else
+        std::cout << "- ";
+    if (input_schema)
+        std::cout   <<  input_schema << "\n";
+    else
+        std::cout   <<  "-\n";
+    std::cout << "match   " << match_syntax << " ";
+    if (match_syntax)
+        std::cout << (oid_getentbyoid(match_syntax))->desc << " ";
+    else
+        std::cout << "- ";
+    if (match_schema)
+        std::cout   <<  match_schema << "\n";
+    else
+        std::cout   <<  "-\n";
+    std::cout << "backend " << backend_syntax << " ";
+    if (backend_syntax)
+        std::cout << (oid_getentbyoid(backend_syntax))->desc << " ";
+    else
+        std::cout << "- ";
+    if (backend_schema)
+        std::cout   <<  backend_schema << "\n";
+    else
+        std::cout   <<  "-\n";
+    
+    // error handeling
+    if (ret_code != 0)
+    {
+
+        // need to construct present error package and send back
+
+        const char *details = 0;
+        if (ret_code == -1) /* error ? */
+        {
+           details = yaz_retrieval_get_error(m_retrieval);
+           std::cout << "ERROR: YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS "
+                     << details << "\n";
+           //rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
+           // if (details)
+           //     rr->errstring = odr_strdup(rr->stream, details);
+        }
+        else if (ret_code == 1 || ret_code == 3)
+        {
+            details = input_schema;
+            std::cout << "ERROR: YAZ_BIB1_ELEMENT_SET_NAMES_UNSUPP "
+                      << details << "\n";
+            //rr->errcode =  YAZ_BIB1_ELEMENT_SET_NAMES_UNSUPP;
+            //if (details)
+            //    rr->errstring = odr_strdup(rr->stream, details);
+        }
+        else if (ret_code == 2)
+        {
+            std::cout << "ERROR: YAZ_BIB1_RECORD_SYNTAX_UNSUPP"
+                      << details << "\n";
+            //rr->errcode = YAZ_BIB1_RECORD_SYNTAX_UNSUPP;
+            //if (input_syntax)
+            //{
+            //    char oidbuf[OID_STR_MAX];
+            //    oid_to_dotstring(input_syntax, oidbuf);
+            //    rr->errstring = odr_strdup(rr->stream, oidbuf);
+            //}
+        }
+        //package.session().close();
+        return;
+    }
+
+
+
+    // now re-coding the z3950 backend present request
      
     // z3950'fy record syntax
-    //Odr_oid odr_oid;
-    if(pr->preferredRecordSyntax){
-        (pr->preferredRecordSyntax)
-            = yaz_str_to_z3950oid(odr_en, CLASS_RECSYN, "xml");
+
+    if (backend_syntax)  // TODO: this seems not to work - why ??
+         pr_req->preferredRecordSyntax
+             = yaz_oidval_to_z3950oid(odr_en, CLASS_RECSYN, *backend_syntax);
+     else
+         pr_req->preferredRecordSyntax
+             = yaz_oidval_to_z3950oid(odr_en, CLASS_RECSYN, VAL_NONE);
+
+     //pr_req->preferredRecordSyntax 
+     //    = yaz_oidval_to_z3950oid (odr_en, CLASS_RECSYN, VAL_TEXT_XML);
         
+
+    //Odr_oid odr_oid;   
         // = yaz_oidval_to_z3950oid (odr_en, CLASS_RECSYN, VAL_TEXT_XML);
-    }
+    // }
     // Odr_oid *yaz_str_to_z3950oid (ODR o, int oid_class,
     //                                         const char *str);
     // const char *yaz_z3950oid_to_str (Odr_oid *oid, int *oid_class);
 
+         //   oident *oident_syntax = oid_getentbyoid(backend_syntax);
+         //
+         //   rr->request_format_raw = backend_syntax;
+         //   
+         //   if (oident_syntax)
+         //       rr->request_format = oident_syntax->value;
+         //   else
+         //       rr->request_format = VAL_NONE;
+         
+
+
 
     // z3950'fy record schema
-    //if ()
-    // {
-    //     pr->recordComposition 
-    //         = (Z_RecordComposition *) 
-    //           odr_malloc(odr_en, sizeof(Z_RecordComposition));
-    //     pr->recordComposition->which 
-    //         = Z_RecordComp_simple;
-    //     pr->recordComposition->u.simple 
-    //         = build_esn_from_schema(odr_en, 
-    //                                 (const char *) sr_req->recordSchema); 
-    // }
+    if (backend_schema)
+    {
+        pr_req->recordComposition 
+            = (Z_RecordComposition *) 
+              odr_malloc(odr_en, sizeof(Z_RecordComposition));
+        pr_req->recordComposition->which 
+            = Z_RecordComp_simple;
+        pr_req->recordComposition->u.simple 
+            = (Z_ElementSetNames *)
+               odr_malloc(odr_en, sizeof(Z_ElementSetNames));
+        pr_req->recordComposition->u.simple->which = Z_ElementSetNames_generic;
+        pr_req->recordComposition->u.simple->u.generic 
+            = odr_strdup(odr_en, backend_schema);
+    }
 
     // attaching Z3950 package to filter chain
     package.request() = gdu_req;
@@ -176,6 +300,86 @@ void yf::RecordTransform::Impl::process(mp::Package &package) const
     // std::cout << "z3950_present_request OK\n";
     // std::cout << "back z3950 " << *gdu_res << "\n";
 
+    Z_PresentResponse * pr_res = gdu_res->u.z3950->u.presentResponse;
+
+    // let non surrogate dioagnostics in Z3950 present response package
+    // pass to frontend - just return
+    if (pr_res->records 
+        && pr_res->records->which == Z_Records_NSD
+        && pr_res->records->u.nonSurrogateDiagnostic)
+        return;
+
+    // record transformation must take place 
+    if (rc && pr_res 
+        && pr_res->numberOfRecordsReturned 
+        && *(pr_res->numberOfRecordsReturned)
+        && pr_res->records
+        && pr_res->records->which == Z_Records_DBOSD
+        && pr_res->records->u.databaseOrSurDiagnostics->num_records)
+    {
+        //transform all records
+         for (int i = 0; 
+              i < pr_res->records->u.databaseOrSurDiagnostics->num_records; 
+              i++)
+         {
+             Z_NamePlusRecord *npr 
+                 = pr_res->records->u.databaseOrSurDiagnostics->records[i];
+             if (npr->which != Z_NamePlusRecord_databaseRecord)
+             {
+                 std::cout  << "TODO: surrogate diag to be set\n";
+             }
+             else
+             {
+                 std::cout  << "TODO: record transform to be done\n";
+                 WRBUF output_record = wrbuf_alloc();
+                 Z_External *r = npr->u.databaseRecord;
+                 //oident *ent = oid_getentbyoid(r->direct_reference);
+                 std::cout 
+                     << "database record type: " << r->which << "\n";
+                 if (r->which == Z_External_octet) 
+                     //&& ent->value == *backend_schema)
+                 {
+                     int ret_trans 
+                         =  yaz_record_conv_record(rc, 
+                                                   (const char *)
+                                                   r->u.octet_aligned->buf, 
+                                                   r->u.octet_aligned->len,
+                                                   output_record);
+                     std::cout 
+                         << "TODO: record transformation error checking\n";
+                }
+                
+             }
+         }
+//&& rr->record && rr->errcode == 0 && rr->len > 0)
+    }
+    
+//         WRBUF output_record = wrbuf_alloc();
+//         int r = yaz_record_conv_record(rc, rr->record, rr->len, output_record);
+//         if (r)
+//         {
+//             const char *details = yaz_record_conv_get_error(rc);
+//             rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
+//             if (details)
+//                 rr->errstring = odr_strdup(rr->stream, details);
+//         }
+//         else
+//         {
+//             rr->len = wrbuf_len(output_record);
+//             rr->record = odr_malloc(rr->stream, rr->len);
+//             memcpy(rr->record, wrbuf_buf(output_record), rr->len);
+//         }
+//         wrbuf_free(output_record, 1);
+//     }
+//     if (match_syntax)
+//     {
+//         struct oident *oi = oid_getentbyoid(match_syntax);
+//         rr->output_format = oi ? oi->value : VAL_NONE;
+//         rr->output_format_raw = match_syntax;
+//     }
+//     if (match_schema)
+//         rr->schema = odr_strdup(rr->stream, match_schema);
+//     return 0;
 
     return;
 }