From: Adam Dickmeiss Date: Wed, 6 Dec 2006 21:35:57 +0000 (+0000) Subject: Changed the SRU update structures and codecs to reflect the SRU pre 1.0 X-Git-Tag: YAZ.2.1.42~24 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=2ede0bb278b22c8ce1cdd48e9a11a5924d433763;hp=3f8685ee91c382bb9769132d6a8692d282edf802 Changed the SRU update structures and codecs to reflect the SRU pre 1.0 spec, at http://www.loc.gov/standards/sru/record-update/ This has changed the binary layout of the following structs: Z_SRW_extra_record, Z_SRW_updateRequest, Z_SRW_updateResponse and bend_update_rr . Patch by Ko van der Sloot. --- diff --git a/NEWS b/NEWS index d494fd0..9933e5a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Changed the SRU update structures and codecs to reflect the SRU pre 1.0 +spec, at http://www.loc.gov/standards/sru/record-update/ +This has changed the binary layout of the following structs: +Z_SRW_extra_record, Z_SRW_updateRequest, Z_SRW_updateResponse and +bend_update_rr . Patch by Ko van der Sloot. + Added GFS utility function bend_assoc_is_alive which returns 1 if association is still alive (client is connected); 0 otherwise (client closed connection). This allows busy servers to stop working for diff --git a/client/client.c b/client/client.c index bb0f250..3ea046e 100644 --- a/client/client.c +++ b/client/client.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: client.c,v 1.319 2006-11-14 08:37:16 adam Exp $ + * $Id: client.c,v 1.320 2006-12-06 21:35:57 adam Exp $ */ /** \file client.c * \brief yaz-client program @@ -2123,20 +2123,20 @@ static int cmd_update0(const char *arg) return cmd_update_common(arg, 0); } +static int cmd_update_Z3950(int version, int action_no, const char *recid, + char *rec_buf, int rec_len); + +static int cmd_update_SRW(int action_no, const char *recid, + char *rec_buf, int rec_len); + static int cmd_update_common(const char *arg, int version) { - Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest ); - Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; - Z_External *r; char action[20], recid[20]; char *rec_buf; int rec_len; int action_no; int noread = 0; - Z_External *record_this = 0; - if (only_z3950()) - return 1; *action = 0; *recid = 0; sscanf (arg, "%19s %19s%n", action, recid, &noread); @@ -2167,6 +2167,57 @@ static int cmd_update_common(const char *arg, int version) if (parse_cmd_doc(&arg, out, &rec_buf, &rec_len, 1) == 0) return 0; + if (protocol == PROTO_HTTP) + return cmd_update_SRW(action_no, recid, rec_buf, rec_len); + else + return cmd_update_Z3950(version, action_no, recid, rec_buf, rec_len); +} + +static int cmd_update_SRW(int action_no, const char *recid, + char *rec_buf, int rec_len) +{ + if (!conn) + cmd_open(0); + if (!conn) + return 0; + else + { + Z_SRW_PDU *srw = yaz_srw_get(out, Z_SRW_update_request); + Z_SRW_updateRequest *sr = srw->u.update_request; + + switch(action_no) + { + case Z_IUOriginPartToKeep_recordInsert: + sr->operation = "info:srw/action/1/create"; + break; + case Z_IUOriginPartToKeep_recordReplace: + sr->operation = "info:srw/action/1/replace"; + break; + case Z_IUOriginPartToKeep_recordDelete: + sr->operation = "info:srw/action/1/delete"; + break; + } + if (rec_buf) + { + sr->record = yaz_srw_get_record(out); + sr->record->recordData_buf = rec_buf; + sr->record->recordData_len = rec_len; + sr->record->recordSchema = record_schema; + } + if (recid) + sr->recordId = odr_strdup(out, recid); + return send_srw(srw); + } +} + +static int cmd_update_Z3950(int version, int action_no, const char *recid, + char *rec_buf, int rec_len) +{ + Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest ); + Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; + Z_External *r; + Z_External *record_this = 0; + if (rec_buf) record_this = z_ext_record (out, VAL_TEXT_XML, rec_buf, rec_len); else @@ -3807,16 +3858,15 @@ static void http_response(Z_HTTP_Response *hres) { Z_SOAP *soap_package = 0; ODR o = odr_createmem(ODR_DECODE); - Z_SOAP_Handler soap_handlers[2] = { - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, + Z_SOAP_Handler soap_handlers[3] = { + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, {0, 0, 0} }; ret = z_soap_codec(o, &soap_package, &hres->content_buf, &hres->content_len, soap_handlers); - if (!ret && soap_package->which == Z_SOAP_generic && - soap_package->u.generic->no == 0) + if (!ret && soap_package->which == Z_SOAP_generic) { Z_SRW_PDU *sr = soap_package->u.generic->p; if (sr->which == Z_SRW_searchRetrieve_response) @@ -3825,11 +3875,14 @@ static void http_response(Z_HTTP_Response *hres) handle_srw_explain_response(sr->u.explain_response); else if (sr->which == Z_SRW_scan_response) handle_srw_scan_response(sr->u.scan_response); + else if (sr->which == Z_SRW_update_response) + printf("Got update response. Status: %s\n", + sr->u.update_response->operationStatus); else ret = -1; } else if (soap_package && (soap_package->which == Z_SOAP_fault - || soap_package->which == Z_SOAP_error)) + || soap_package->which == Z_SOAP_error)) { printf ("HTTP Error Status=%d\n", hres->code); printf ("SOAP Fault code %s\n", @@ -3841,7 +3894,10 @@ static void http_response(Z_HTTP_Response *hres) soap_package->u.fault->details); } else + { + printf("z_soap_codec failed. (no SOAP error)\n"); ret = -1; + } odr_destroy(o); } if (ret) diff --git a/include/yaz/backend.h b/include/yaz/backend.h index ff0b15d..a0a59e8 100644 --- a/include/yaz/backend.h +++ b/include/yaz/backend.h @@ -24,7 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: backend.h,v 1.39 2006-12-04 14:56:54 adam Exp $ */ +/* $Id: backend.h,v 1.40 2006-12-06 21:35:58 adam Exp $ */ /** * \file backend.h @@ -154,14 +154,12 @@ typedef struct bend_update_rr { char *operation; char *operation_status; char *record_id; - char *record_version; - char *record_checksum; - char *record_old_version; + Z_SRW_recordVersion *record_versions; + int num_versions; char *record_packing; char *record_schema; char *record_data; - Z_SRW_extra_record *request_extra_record; - Z_SRW_extra_record *response_extra_record; + char *extra_record_data; char *extra_request_data; char *extra_response_data; char *uri; diff --git a/include/yaz/log.h b/include/yaz/log.h index 6821856..1b0a6c4 100644 --- a/include/yaz/log.h +++ b/include/yaz/log.h @@ -24,7 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: log.h,v 1.39 2006-10-09 21:02:41 adam Exp $ */ +/* $Id: log.h,v 1.40 2006-12-06 21:35:58 adam Exp $ */ /** * \file log.h @@ -196,9 +196,7 @@ YAZ_EXPORT void log_event_start(void (*func)(int level, const char *msg, YAZ_EXPORT void log_event_end(void (*func)(int level, const char *msg, void *info), void *info); -#if YAZ_USE_NEW_LOG - -#else +#if YAZ_USE_OLD_LOG #include @@ -239,7 +237,7 @@ YAZ_EXPORT void log_event_end(void (*func)(int level, const char *msg, /** \brief logf is deprecated, as it conflicts with a math function */ #define logf yaz_log -#endif /* if YAZ_USE_NEW_LOG */ +#endif /* if YAZ_USE_OLD_LOG */ YAZ_END_CDECL diff --git a/include/yaz/srw.h b/include/yaz/srw.h index 14dc8b9..6e563f5 100644 --- a/include/yaz/srw.h +++ b/include/yaz/srw.h @@ -24,7 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: srw.h,v 1.31 2006-10-27 11:22:08 adam Exp $ */ +/* $Id: srw.h,v 1.32 2006-12-06 21:35:58 adam Exp $ */ /** * \file srw.h @@ -42,13 +42,9 @@ YAZ_BEGIN_CDECL typedef struct { - int type; - char *recordReviewCode; - char *recordReviewNote; - char *recordId; - char *nonDupRecordId; - char *recordLockStatus; - char *recordOldVersion; + char *extraRecordData_buf; + int extraRecordData_len; + char *recordIdentifier; } Z_SRW_extra_record; typedef struct { @@ -156,25 +152,32 @@ typedef struct { typedef struct { + char *versionType; + char *versionValue; +} Z_SRW_recordVersion; + +typedef struct { char *database; char *operation; char *recordId; - char *recordVersion; - char *recordOldVersion; - Z_SRW_record record; + Z_SRW_recordVersion *recordVersions; + int num_recordVersions; + Z_SRW_record *record; Z_SRW_extra_record *extra_record; - char *extraRequestData; + char *extraRequestData_buf; + int extraRequestData_len; char *stylesheet; } Z_SRW_updateRequest; typedef struct { char *operationStatus; char *recordId; - char *recordVersion; - char *recordChecksum; - char *extraResponseData; - Z_SRW_record record; + Z_SRW_recordVersion *recordVersions; + int num_recordVersions; + Z_SRW_record *record; Z_SRW_extra_record *extra_record; + char *extraResponseData_buf; + int extraResponseData_len; Z_SRW_diagnostic *diagnostics; int num_diagnostics; } Z_SRW_updateResponse; @@ -214,12 +217,18 @@ YAZ_EXPORT int yaz_ucp_codec(ODR o, void * pptr, void *client_data, const char *ns); YAZ_EXPORT Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o); YAZ_EXPORT Z_SRW_PDU *yaz_srw_get(ODR o, int which); +YAZ_EXPORT Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR o, int num); YAZ_EXPORT Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o); +YAZ_EXPORT Z_SRW_record *yaz_srw_get_record(ODR o); +YAZ_EXPORT Z_SRW_record *yaz_srw_get_records(ODR o, int num); YAZ_EXPORT int yaz_diag_bib1_to_srw (int bib1_code); YAZ_EXPORT int yaz_diag_srw_to_bib1(int srw_code); +YAZ_EXPORT const char *yaz_srw_pack_to_str(int pack); +YAZ_EXPORT int yaz_srw_str_to_pack(const char *str); + YAZ_EXPORT char *yaz_uri_val(const char *path, const char *name, ODR o); YAZ_EXPORT void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp); @@ -257,6 +266,11 @@ YAZ_EXPORT int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, YAZ_EXPORT int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, ODR odr, const char *charset); +#define YAZ_XMLNS_SRU_v1_0 "http://www.loc.gov/zing/srw/v1.0/" +#define YAZ_XMLNS_SRU_v1_1 "http://www.loc.gov/zing/srw/" +#define YAZ_XMLNS_DIAG_v1_1 "http://www.loc.gov/zing/srw/diagnostic/" +#define YAZ_XMLNS_UPDATE_v0_9 "http://www.loc.gov/zing/srw/update/" + YAZ_END_CDECL #endif diff --git a/src/seshigh.c b/src/seshigh.c index e29973e..a91c70a 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.105 2006-12-04 14:56:55 adam Exp $ + * $Id: seshigh.c,v 1.106 2006-12-06 21:35:58 adam Exp $ */ /** * \file seshigh.c @@ -1060,11 +1060,12 @@ static void srw_bend_search(association *assoc, request *req, { int j = 0; int packing = Z_SRW_recordPacking_string; - if (srw_req->recordPacking){ - if (!strcmp(srw_req->recordPacking, "xml")) - packing = Z_SRW_recordPacking_XML; - if (!strcmp(srw_req->recordPacking, "url")) - packing = Z_SRW_recordPacking_URL; + if (srw_req->recordPacking) + { + packing = + yaz_srw_str_to_pack(srw_req->recordPacking); + if (packing == -1) + packing = Z_SRW_recordPacking_string; } srw_res->records = (Z_SRW_record *) odr_malloc(assoc->encode, @@ -1073,7 +1074,7 @@ static void srw_bend_search(association *assoc, request *req, srw_res->extra_records = (Z_SRW_extra_record **) odr_malloc(assoc->encode, number*sizeof(*srw_res->extra_records)); - + for (i = 0; irecordPacking) { - if (!strcmp(srw_req->recordPacking, "xml")) - packing = Z_SRW_recordPacking_XML; - else if (!strcmp(srw_req->recordPacking, "url")) - packing = Z_SRW_recordPacking_URL; + packing = + yaz_srw_str_to_pack(srw_req->recordPacking); + if (packing == -1) + packing = Z_SRW_recordPacking_string; } srw_res->record.recordSchema = rr.schema; srw_res->record.recordPacking = packing; @@ -1432,13 +1433,14 @@ static void srw_bend_update(association *assoc, request *req, int *http_code) { Z_SRW_updateRequest *srw_req = sr->u.update_request; - yaz_log(YLOG_DEBUG, "Got SRW UpdateRequest"); + yaz_log(log_session, "SRWUpdate action=%s", srw_req->operation); yaz_log(YLOG_DEBUG, "num_diag = %d", srw_res->num_diagnostics ); *http_code = 404; srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr); if (assoc->init) { bend_update_rr rr; + Z_SRW_extra_record *extra = srw_req->extra_record; rr.stream = assoc->encode; rr.print = assoc->print; @@ -1447,183 +1449,169 @@ static void srw_bend_update(association *assoc, request *req, rr.operation = srw_req->operation; rr.operation_status = "failed"; rr.record_id = 0; - rr.record_version = 0; - rr.record_checksum = 0; - rr.record_old_version = 0; - rr.record_packing = "xml"; + rr.record_versions = 0; + rr.num_versions = 0; + rr.record_packing = "string"; rr.record_schema = 0; rr.record_data = 0; - rr.request_extra_record = 0; - rr.response_extra_record = 0; + rr.extra_record_data = 0; rr.extra_request_data = 0; rr.extra_response_data = 0; rr.uri = 0; rr.message = 0; rr.details = 0; - if ( rr.operation == 0 ){ - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "action" ); + *http_code = 200; + if (rr.operation == 0) + { + yaz_add_sru_update_diagnostic( + assoc->encode, &srw_res->diagnostics, + &srw_res->num_diagnostics, + YAZ_SRU_UPDATE_MISSING_MANDATORY_ELEMENT_RECORD_REJECTED, + "action" ); return; } yaz_log(YLOG_DEBUG, "basename = %s", rr.basenames[0] ); yaz_log(YLOG_DEBUG, "Operation = %s", rr.operation ); - if ( !strcmp( rr.operation, "delete" ) ){ - if ( !srw_req->recordId ){ - if ( srw_req->record.recordData_len ){ - if ( srw_req->record.recordSchema == 0 ){ - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordSchema" ); - } - else { - rr.record_schema = odr_strdup(assoc->encode, - srw_req->record.recordSchema ); - } - switch (srw_req->record.recordPacking) - { - case Z_SRW_recordPacking_string: - rr.record_packing = "string"; - break; - case Z_SRW_recordPacking_XML: - rr.record_packing = "xml"; - break; - case Z_SRW_recordPacking_URL: - rr.record_packing = "url"; - break; - } - rr.record_data = odr_strdupn(assoc->encode, - srw_req->record.recordData_buf, - srw_req->record.recordData_len ); - rr.request_extra_record = srw_req->extra_record; - } - else { - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordIdentifier OR recordData" ); - } - } - else { - rr.record_id = srw_req->recordId; - if ( srw_req->record.recordData_len ){ - yaz_add_sru_update_diagnostic(assoc->encode, - &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordData" ); - } - } - if ( srw_req->recordVersion ){ - rr.record_version = odr_strdup( assoc->encode, - srw_req->recordVersion ); - + if (!strcmp( rr.operation, "delete")) + { + if (srw_req->record && !srw_req->record->recordSchema) + { + rr.record_schema = odr_strdup( + assoc->encode, + srw_req->record->recordSchema); } - if ( srw_req->recordOldVersion ){ - rr.record_old_version = odr_strdup(assoc->encode, - srw_req->recordOldVersion ); + if (srw_req->record) + { + rr.record_data = odr_strdupn( + assoc->encode, + srw_req->record->recordData_buf, + srw_req->record->recordData_len ); } - if ( srw_req->extraRequestData ){ - rr.extra_request_data = odr_strdup(assoc->encode, - srw_req->extraRequestData ); + if (extra && extra->extraRecordData_len) + { + rr.extra_record_data = odr_strdupn( + assoc->encode, + extra->extraRecordData_buf, + extra->extraRecordData_len ); } + if (srw_req->recordId) + rr.record_id = srw_req->recordId; + else if (extra && extra->recordIdentifier) + rr.record_id = extra->recordIdentifier; } - else if ( !strcmp( rr.operation, "replace" ) ){ - if ( !srw_req->recordId ){ - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordIdentifier" ); - } - else { + else if (!strcmp(rr.operation, "replace")) + { + if (srw_req->recordId) rr.record_id = srw_req->recordId; + else if (extra && extra->recordIdentifier) + rr.record_id = extra->recordIdentifier; + else + { + yaz_add_sru_update_diagnostic( + assoc->encode, &srw_res->diagnostics, + &srw_res->num_diagnostics, + YAZ_SRU_UPDATE_MISSING_MANDATORY_ELEMENT_RECORD_REJECTED, + "recordIdentifier"); } - if ( srw_req->record.recordSchema == 0 ){ - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordSchema" ); - } - else { - rr.record_schema = odr_strdup(assoc->encode, - srw_req->record.recordSchema ); - } - switch (srw_req->record.recordPacking) + if (!srw_req->record) { - case Z_SRW_recordPacking_string: - rr.record_packing = "string"; - break; - case Z_SRW_recordPacking_XML: - rr.record_packing = "xml"; - break; - case Z_SRW_recordPacking_URL: - rr.record_packing = "url"; - break; + yaz_add_sru_update_diagnostic( + assoc->encode, &srw_res->diagnostics, + &srw_res->num_diagnostics, + YAZ_SRU_UPDATE_MISSING_MANDATORY_ELEMENT_RECORD_REJECTED, + "record"); } - if ( srw_req->record.recordData_len ){ - rr.record_data = odr_strdupn(assoc->encode, - srw_req->record.recordData_buf, - srw_req->record.recordData_len ); - rr.request_extra_record = srw_req->extra_record; + else + { + if (srw_req->record->recordSchema) + rr.record_schema = odr_strdup( + assoc->encode, srw_req->record->recordSchema); + if (srw_req->record->recordData_len ) + { + rr.record_data = odr_strdupn(assoc->encode, + srw_req->record->recordData_buf, + srw_req->record->recordData_len ); + } + else + { + yaz_add_sru_update_diagnostic( + assoc->encode, &srw_res->diagnostics, + &srw_res->num_diagnostics, + YAZ_SRU_UPDATE_MISSING_MANDATORY_ELEMENT_RECORD_REJECTED, + "recordData" ); + } } - else { - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordData" ); + if (extra && extra->extraRecordData_len) + { + rr.extra_record_data = odr_strdupn( + assoc->encode, + extra->extraRecordData_buf, + extra->extraRecordData_len ); } - if (srw_req->extraRequestData) - rr.extra_request_data = odr_strdup(assoc->encode, - srw_req->extraRequestData ); } - else if (!strcmp( rr.operation, "insert" ) ) { - rr.record_id = srw_req->recordId; - if ( srw_req->record.recordSchema == 0 ){ - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordSchema" ); - } - else { - rr.record_schema = odr_strdup(assoc->encode, - srw_req->record.recordSchema); - } - switch (srw_req->record.recordPacking) + else if (!strcmp(rr.operation, "insert")) + { + if (srw_req->recordId) + rr.record_id = srw_req->recordId; + else if (extra) + rr.record_id = extra->recordIdentifier; + + if (srw_req->record) { - case Z_SRW_recordPacking_string: - rr.record_packing = "string"; - break; - case Z_SRW_recordPacking_XML: - rr.record_packing = "xml"; - break; - case Z_SRW_recordPacking_URL: - rr.record_packing = "url"; - break; - } + if (srw_req->record->recordSchema) + rr.record_schema = odr_strdup( + assoc->encode, srw_req->record->recordSchema); - if (srw_req->record.recordData_len) + if (srw_req->record->recordData_len) + rr.record_data = odr_strdupn( + assoc->encode, + srw_req->record->recordData_buf, + srw_req->record->recordData_len ); + } + if (extra && extra->extraRecordData_len) { - rr.record_data = odr_strdupn(assoc->encode, - srw_req->record.recordData_buf, - srw_req->record.recordData_len ); - rr.request_extra_record = srw_req->extra_record; + rr.extra_record_data = odr_strdupn( + assoc->encode, + extra->extraRecordData_buf, + extra->extraRecordData_len ); } - else - yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, - &srw_res->num_diagnostics, - 9, "recordData" ); - if ( srw_req->extraRequestData ) - rr.extra_request_data = odr_strdup(assoc->encode, - srw_req->extraRequestData ); } - else { + else yaz_add_sru_update_diagnostic(assoc->encode, &srw_res->diagnostics, &srw_res->num_diagnostics, - 100, rr.operation ); + YAZ_SRU_UPDATE_INVALID_ACTION, + rr.operation ); + + if (srw_req->record) + { + const char *pack_str = + yaz_srw_pack_to_str(srw_req->record->recordPacking); + if (pack_str) + rr.record_packing = odr_strdup(assoc->encode, pack_str); + } + + if (srw_req->num_recordVersions) + { + rr.record_versions = srw_req->recordVersions; + rr.num_versions = srw_req->num_recordVersions; + } + if (srw_req->extraRequestData_len) + { + rr.extra_request_data = odr_strdupn(assoc->encode, + srw_req->extraRequestData_buf, + srw_req->extraRequestData_len ); } if (srw_res->num_diagnostics == 0) { if ( assoc->init->bend_srw_update) (*assoc->init->bend_srw_update)(assoc->backend, &rr); - else { - yaz_log( YLOG_WARN, "Got No Update function!"); - return; - } + else + yaz_add_sru_update_diagnostic( + assoc->encode, &srw_res->diagnostics, + &srw_res->num_diagnostics, + YAZ_SRU_UPDATE_UNSPECIFIED_DATABASE_ERROR, + "No Update backend handler"); } if (rr.uri) @@ -1635,22 +1623,40 @@ static void srw_bend_update(association *assoc, request *req, rr.details); srw_res->recordId = rr.record_id; srw_res->operationStatus = rr.operation_status; - srw_res->recordVersion = rr.record_version; - srw_res->recordChecksum = rr.record_checksum; - srw_res->extraResponseData = rr.extra_response_data; - srw_res->record.recordPosition = 0; + srw_res->recordVersions = rr.record_versions; + srw_res->num_recordVersions = rr.num_versions; + if (srw_res->extraResponseData_len) + { + srw_res->extraResponseData_buf = rr.extra_response_data; + srw_res->extraResponseData_len = strlen(rr.extra_response_data); + } if (srw_res->num_diagnostics == 0 && rr.record_data) - { - srw_res->record.recordSchema = rr.record_schema; - srw_res->record.recordPacking = srw_req->record.recordPacking; - srw_res->record.recordData_buf = rr.record_data; - srw_res->record.recordData_len = strlen(rr.record_data); - srw_res->extra_record = rr.response_extra_record; - - } - else - srw_res->record.recordData_len = 0; - *http_code = 200; + { + srw_res->record = yaz_srw_get_record(assoc->encode); + srw_res->record->recordSchema = rr.record_schema; + if (rr.record_packing) + { + int pack = yaz_srw_str_to_pack(rr.record_packing); + + if (pack == -1) + { + pack = Z_SRW_recordPacking_string; + yaz_log(YLOG_WARN, "Back packing %s from backend", + rr.record_packing); + } + srw_res->record->recordPacking = pack; + } + srw_res->record->recordData_buf = rr.record_data; + srw_res->record->recordData_len = strlen(rr.record_data); + if (rr.extra_record_data) + { + Z_SRW_extra_record *ex = + yaz_srw_get_extra_record(assoc->encode); + srw_res->extra_record = ex; + ex->extraRecordData_buf = rr.extra_record_data; + ex->extraRecordData_len = strlen(rr.extra_record_data); + } + } } } @@ -1849,12 +1855,9 @@ static void process_http_request(association *assoc, request *req) { static Z_SOAP_Handler soap_handlers[4] = { #if YAZ_HAVE_XML2 - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, - {"http://www.loc.gov/zing/srw/v1.0/", 0, - (Z_SOAP_fun) yaz_srw_codec}, - {"http://www.loc.gov/zing/srw/update/", 0, - (Z_SOAP_fun) yaz_ucp_codec}, + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, #endif {0, 0, 0} }; @@ -2131,7 +2134,6 @@ static int process_gdu_response(association *assoc, request *req, Z_GDU *res) req = request_head(&assoc->incoming); if (req && req->state == REQUEST_IDLE) { - yaz_log(YLOG_LOG, "process next request 3"); request_deq(&assoc->incoming); process_gdu_request(assoc, req); } @@ -2349,7 +2351,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) assoc->init->implementation_name, odr_prepend(assoc->encode, "GFS", resp->implementationName)); - version = odr_strdup(assoc->encode, "$Revision: 1.105 $"); + version = odr_strdup(assoc->encode, "$Revision: 1.106 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; resp->implementationVersion = odr_prepend(assoc->encode, diff --git a/src/sru_update.csv b/src/sru_update.csv index 354f742..547105a 100644 --- a/src/sru_update.csv +++ b/src/sru_update.csv @@ -43,5 +43,6 @@ 59, "Suspect duplicate: warning only" 60, "Incoming record matches with database record, records merged" 61, "Unspecified database error" -62, "Cannot process or store record, insufficient space" +63, " 'record' is ignored, while Both 'recordIdentifier' and 'record' were included on a 'delete' action." +64, "'recordIdentifier' is ignored, while Both 'recordIdentifier' and 'record' were included on a 'delete' action." 100, "invalid action" \ No newline at end of file diff --git a/src/srw.c b/src/srw.c index a9430b0..bda1844 100644 --- a/src/srw.c +++ b/src/srw.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: srw.c,v 1.51 2006-11-30 22:58:06 adam Exp $ + * $Id: srw.c,v 1.52 2006-12-06 21:35:58 adam Exp $ */ /** * \file srw.c @@ -15,14 +15,15 @@ #include #include -static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len) +static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len, + xmlNsPtr ns_ptr) { if (val) { xmlDocPtr doc = xmlParseMemory(val,len); if (doc) { - xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0); + xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0); xmlNodePtr t = xmlDocGetRootElement(doc); xmlAddChild(c, xmlCopyNode(t,1)); xmlFreeDoc(doc); @@ -43,14 +44,24 @@ xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, return 0; } -xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val) +xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val, + xmlNsPtr ns_ptr) { if (val) - return xmlNewTextChild(ptr, 0, BAD_CAST elem, - BAD_CAST val); + { + xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0); + xmlNodePtr t = xmlNewText(BAD_CAST val); + xmlAddChild(c, t); + return t; + } return 0; } +xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val) +{ + return add_xsd_string_ns(ptr, elem, val, 0); +} + static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val) { if (val) @@ -64,7 +75,9 @@ static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val) static int match_element(xmlNodePtr ptr, const char *elem) { if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem)) + { return 1; + } return 0; } @@ -215,70 +228,14 @@ static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val) return 1; } -static int yaz_srw_extra_record(ODR o, xmlNodePtr pptr, - Z_SRW_extra_record *rec, - void *client_data, const char *ns) -{ - if (o->direction == ODR_DECODE) - { - xmlNodePtr ptr; - rec->type = 1; - rec->recordId = 0; - rec->recordReviewCode = 0; - rec->recordReviewNote = 0; - rec->recordLockStatus = 0; - rec->recordOldVersion = 0; - rec->nonDupRecordId = 0; - for (ptr = pptr->children; ptr; ptr = ptr->next) - { - if (match_xsd_string(ptr, "recordId", o, - &rec->recordId )) - ; /* backward compatible */ - else if (match_xsd_string(ptr, "recordIdentifier", o, - &rec->recordId )) - ; - else if (match_xsd_string(ptr, "recordReviewCode", o, - &rec->recordReviewCode )) - ; - else if (match_xsd_string(ptr, "recordReviewNote", o, - &rec->recordReviewNote )) - ; - else if (match_xsd_string(ptr, "nonDupRecordId", o, - &rec->nonDupRecordId )) - ; - else if (match_xsd_string(ptr, "recordLockStatus", o, - &rec->recordLockStatus )) - ; - else if (match_xsd_string(ptr, "recordOldVersion", o, - &rec->recordOldVersion )) - ; - } - } - else if (o->direction == ODR_ENCODE) - { - xmlNodePtr ptr = pptr; - if ( rec->recordId ) - add_xsd_string(ptr, "recordIdentfier", rec->recordId); - if ( rec->recordReviewCode ) - add_xsd_string(ptr, "recordReviewCode", rec->recordReviewCode); - if ( rec->recordReviewNote ) - add_xsd_string(ptr, "recordReviewNote", rec->recordReviewNote); - if ( rec->nonDupRecordId ) - add_xsd_string(ptr, "nonDupRecordId", rec->nonDupRecordId); - if ( rec->recordLockStatus ) - add_xsd_string(ptr, "recordLockStatus", rec->recordLockStatus); - if ( rec->recordOldVersion ) - add_xsd_string(ptr, "recordOldVersion", rec->recordOldVersion); - } - return 0; -} - static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, Z_SRW_extra_record **extra, void *client_data, const char *ns) { if (o->direction == ODR_DECODE) { + Z_SRW_extra_record ex; + char *spack = 0; int pack = Z_SRW_recordPacking_string; xmlNodePtr ptr; @@ -288,6 +245,11 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, rec->recordData_len = 0; rec->recordPosition = 0; *extra = 0; + + ex.extraRecordData_buf = 0; + ex.extraRecordData_len = 0; + ex.recordIdentifier = 0; + for (ptr = pptr->children; ptr; ptr = ptr->next) { @@ -314,12 +276,14 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, */ data_ptr = ptr; } - else if (match_element(ptr, "extraRecordData")) - { - *extra = (Z_SRW_extra_record *) - odr_malloc(o, sizeof(Z_SRW_extra_record)); - yaz_srw_extra_record(o, ptr, *extra, client_data, ns); - } + else if (match_xsd_XML_n(ptr, "extraRecordData", o, + &ex.extraRecordData_buf, + &ex.extraRecordData_len) ) + ; + else if (match_xsd_string(ptr, "recordIdentifier", o, + &ex.recordIdentifier)) + ; + } if (data_ptr) { @@ -342,6 +306,12 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, } } rec->recordPacking = pack; + if (ex.extraRecordData_buf || ex.recordIdentifier) + { + *extra = (Z_SRW_extra_record *) + odr_malloc(o, sizeof(Z_SRW_extra_record)); + memcpy(*extra, &ex, sizeof(Z_SRW_extra_record)); + } } else if (o->direction == ODR_ENCODE) { @@ -359,7 +329,7 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, case Z_SRW_recordPacking_XML: add_xsd_string(ptr, "recordPacking", "xml"); add_XML_n(ptr, "recordData", rec->recordData_buf, - rec->recordData_len); + rec->recordData_len, 0); break; case Z_SRW_recordPacking_URL: add_xsd_string(ptr, "recordPacking", "url"); @@ -371,9 +341,13 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, add_xsd_integer(ptr, "recordPosition", rec->recordPosition ); if (extra && *extra) { - xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "extraRecordData", - 0); - yaz_srw_extra_record(o, rptr, *extra, client_data, ns); + if ((*extra)->recordIdentifier) + add_xsd_string(ptr, "recordIdentifier", + (*extra)->recordIdentifier); + if ((*extra)->extraRecordData_buf) + add_XML_n(ptr, "extraRecordData", + (*extra)->extraRecordData_buf, + (*extra)->extraRecordData_len, 0); } } return 0; @@ -422,6 +396,75 @@ static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, return 0; } +static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec, + void *client_data, const char *ns) +{ + if (o->direction == ODR_DECODE) + { + xmlNodePtr ptr; + rec->versionType = 0; + rec->versionValue = 0; + for (ptr = pptr->children; ptr; ptr = ptr->next) + { + + if (match_xsd_string(ptr, "versionType", o, + &rec->versionType)) + ; + else if (match_xsd_string(ptr, "versionValue", o, + &rec->versionValue)) + ; + } + } + else if (o->direction == ODR_ENCODE) + { + xmlNodePtr ptr = pptr; + add_xsd_string(ptr, "versionType", rec->versionType); + add_xsd_string(ptr, "versionValue", rec->versionValue); + } + return 0; +} + +static int yaz_srw_versions(ODR o, xmlNodePtr pptr, + Z_SRW_recordVersion **vers, + int *num, void *client_data, const char *ns) +{ + if (o->direction == ODR_DECODE) + { + int i; + xmlNodePtr ptr; + *num = 0; + for (ptr = pptr->children; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE && + !xmlStrcmp(ptr->name, BAD_CAST "recordVersion")) + (*num)++; + } + if (!*num) + return 1; + *vers = (Z_SRW_recordVersion *) odr_malloc(o, *num * sizeof(**vers)); + for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE && + !xmlStrcmp(ptr->name, BAD_CAST "recordVersion")) + { + yaz_srw_version(o, ptr, *vers + i, client_data, ns); + i++; + } + } + } + else if (o->direction == ODR_ENCODE) + { + int i; + for (i = 0; i < *num; i++) + { + xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "version", + 0); + yaz_srw_version(o, rptr, (*vers)+i, client_data, ns); + } + } + return 0; +} + static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, int *num, void *client_data, const char *ns) { @@ -474,8 +517,7 @@ static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, { int i; xmlNsPtr ns_diag = - xmlNewNs(pptr, BAD_CAST - "http://www.loc.gov/zing/srw/diagnostic/", 0); + xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1, BAD_CAST "diag" ); for (i = 0; i < *num; i++) { const char *std_diag = "info:srw/diagnostic/1/"; @@ -702,7 +744,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, ; else if (match_element(ptr, "records")) yaz_srw_records(o, ptr, &res->records, - &res->extra_records, + &res->extra_records, &res->num_records, client_data, ns); else if (match_xsd_integer(ptr, "nextRecordPosition", o, &res->nextRecordPosition)) @@ -1012,9 +1054,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, } int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, - void *client_data, const char *ns) + void *client_data, const char *ns_ucp_str) { xmlNodePtr pptr = (xmlNodePtr) vptr; + const char *ns_srw_str = YAZ_XMLNS_SRU_v1_1; if (o->direction == ODR_DECODE) { Z_SRW_PDU **p = handler_data; @@ -1042,14 +1085,12 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req->database = 0; req->operation = 0; req->recordId = 0; - req->recordVersion = 0; - req->recordOldVersion = 0; - req->record.recordData_buf = 0; - req->record.recordData_len = 0; - req->record.recordSchema = 0; - req->record.recordPacking = 0; + req->recordVersions = 0; + req->num_recordVersions = 0; + req->record = 0; req->extra_record = 0; - req->extraRequestData = 0; + req->extraRequestData_buf = 0; + req->extraRequestData_len = 0; req->stylesheet = 0; for (; ptr; ptr = ptr->next) @@ -1057,18 +1098,6 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_string(ptr, "operation", o, - &oper)){ - /* backward compatible */ - if ( oper ){ - if ( !strcmp(oper, "delete")) - req->operation = "delete"; - else if (!strcmp(oper,"replace" )) - req->operation = "replace"; - else if ( !strcmp( oper, "insert")) - req->operation = "insert"; - } - } else if (match_xsd_string(ptr, "action", o, &oper)){ if ( oper ){ @@ -1080,18 +1109,19 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req->operation = "insert"; } } - else if (match_xsd_string(ptr, "recordId", o, - &req->recordId)) - ; /* backward compatible */ else if (match_xsd_string(ptr, "recordIdentifier", o, &req->recordId)) ; - else if (match_xsd_string(ptr, "recordVersion", o, - &req->recordVersion)) - ; + else if (match_element(ptr, "recordVersions" ) ) + yaz_srw_versions( o, ptr, &req->recordVersions, + &req->num_recordVersions, client_data, + ns_ucp_str); else if (match_element(ptr, "record")) - yaz_srw_record(o, ptr, &req->record, &req->extra_record, - client_data, ns); + { + req->record = yaz_srw_get_record(o); + yaz_srw_record(o, ptr, req->record, &req->extra_record, + client_data, ns_ucp_str); + } else if (match_xsd_string(ptr, "stylesheet", o, &req->stylesheet)) ; @@ -1111,16 +1141,14 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, res->operationStatus = 0; res->recordId = 0; - res->recordVersion = 0; - res->recordChecksum = 0; + res->recordVersions = 0; + res->num_recordVersions = 0; res->diagnostics = 0; res->num_diagnostics = 0; - res->record.recordData_buf = 0; - res->record.recordData_len = 0; - res->record.recordSchema = 0; - res->record.recordPacking = 0; + res->record = 0; res->extra_record = 0; - res->extraResponseData = 0; + res->extraResponseData_buf = 0; + res->extraResponseData_len = 0; for (; ptr; ptr = ptr->next) { @@ -1130,22 +1158,23 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if (match_xsd_string(ptr, "operationStatus", o, &res->operationStatus )) ; - else if (match_xsd_string(ptr, "recordId", o, - &res->recordId)) - ; /* backward compatible */ else if (match_xsd_string(ptr, "recordIdentifier", o, &res->recordId)) ; - else if (match_xsd_string(ptr, "recordVersion", o, - &res->recordVersion )) - ; + else if (match_element(ptr, "recordVersions" )) + yaz_srw_versions(o, ptr, &res->recordVersions, + &res->num_recordVersions, + client_data, ns_ucp_str); else if (match_element(ptr, "record")) - yaz_srw_record(o, ptr, &res->record, &res->extra_record, - client_data, ns); + { + res->record = yaz_srw_get_record(o); + yaz_srw_record(o, ptr, res->record, &res->extra_record, + client_data, ns_ucp_str); + } else if (match_element(ptr, "diagnostics")) yaz_srw_diagnostics(o, ptr, &res->diagnostics, &res->num_diagnostics, - client_data, ns); + client_data, ns_ucp_str); } } else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest")) @@ -1163,16 +1192,37 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if (o->direction == ODR_ENCODE) { Z_SRW_PDU **p = handler_data; - xmlNsPtr ns_srw; + xmlNsPtr ns_ucp, ns_srw; + if ((*p)->which == Z_SRW_update_request) { Z_SRW_updateRequest *req = (*p)->u.update_request; xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0); - ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zu"); - xmlSetNs(ptr, ns_srw); - - add_xsd_string(ptr, "version", (*p)->srw_version); + ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu"); + xmlSetNs(ptr, ns_ucp); + ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs"); + + add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw); + add_xsd_string(ptr, "action", req->operation); + add_xsd_string(ptr, "recordIdentifier", req->recordId ); + if (req->recordVersions) + yaz_srw_versions( o, ptr, &req->recordVersions, + &req->num_recordVersions, + client_data, ns_ucp_str); + if (req->record && req->record->recordData_len) + { + xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0); + xmlSetNs(rptr, ns_srw); + yaz_srw_record(o, rptr, req->record, &req->extra_record, + client_data, ns_ucp_str); + } + if (req->extraRequestData_len) + { + add_XML_n(ptr, "extraRequestData", + req->extraRequestData_buf, + req->extraRequestData_len, ns_srw); + } add_xsd_string(ptr, "stylesheet", req->stylesheet); add_xsd_string(ptr, "database", req->database); } @@ -1181,30 +1231,39 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, Z_SRW_updateResponse *res = (*p)->u.update_response; xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *) "updateResponse", 0); - ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zu"); - xmlSetNs(ptr, ns_srw); + ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu"); + xmlSetNs(ptr, ns_ucp); + ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs"); - add_xsd_string(ptr, "version", (*p)->srw_version); + add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw); add_xsd_string(ptr, "operationStatus", res->operationStatus ); add_xsd_string(ptr, "recordIdentifier", res->recordId ); - if (res->recordVersion) - add_xsd_string(ptr, "recordVersion", res->recordVersion ); - if (res->recordChecksum) - add_xsd_string(ptr, "recordChecksum", res->recordChecksum ); - if (res->record.recordData_len) + if (res->recordVersions) + yaz_srw_versions(o, ptr, &res->recordVersions, + &res->num_recordVersions, + client_data, ns_ucp_str); + if (res->record && res->record->recordData_len) { xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0); - yaz_srw_record(o, rptr, &res->record, &res->extra_record, - client_data, ns); + xmlSetNs(rptr, ns_srw); + yaz_srw_record(o, rptr, res->record, &res->extra_record, + client_data, ns_ucp_str); } if (res->num_diagnostics) { - xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics", 0); + xmlNsPtr ns_diag = + xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1, + BAD_CAST "diag" ); + + xmlNodePtr rptr = xmlNewChild(ptr, ns_diag, BAD_CAST "diagnostics", 0); yaz_srw_diagnostics(o, rptr, &res->diagnostics, - &res->num_diagnostics, client_data, ns); + &res->num_diagnostics, client_data, + ns_ucp_str); } - if ( res->extraResponseData ) - add_xsd_string(ptr, "extraResponseData", res->extraResponseData); + if (res->extraResponseData_len) + add_XML_n(ptr, "extraResponseData", + res->extraResponseData_buf, + res->extraResponseData_len, ns_srw); } else return -1; diff --git a/src/srwutil.c b/src/srwutil.c index 560976b..bb2da66 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: srwutil.c,v 1.53 2006-10-27 11:22:09 adam Exp $ + * $Id: srwutil.c,v 1.54 2006-12-06 21:35:58 adam Exp $ */ /** * \file srwutil.c @@ -376,12 +376,9 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, static Z_SOAP_Handler soap_handlers[4] = { #if YAZ_HAVE_XML2 - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, - {"http://www.loc.gov/zing/srw/v1.0/", 0, - (Z_SOAP_fun) yaz_srw_codec}, - {"http://www.loc.gov/zing/srw/update/", 0, - (Z_SOAP_fun) yaz_ucp_codec}, + { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec }, + { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec }, + { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec }, #endif {0, 0, 0} }; @@ -464,8 +461,7 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, { #if YAZ_HAVE_XML2 static Z_SOAP_Handler soap_handlers[2] = { - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; #endif @@ -770,16 +766,35 @@ Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o) { Z_SRW_extra_record *res = (Z_SRW_extra_record *) odr_malloc(o, sizeof(*res)); - res->type = 1; - res->recordReviewCode = 0; - res->recordReviewNote = 0; - res->recordId = 0; - res->nonDupRecordId = 0; - res->recordLockStatus = 0; - res->recordOldVersion = 0; + + res->extraRecordData_buf = 0; + res->extraRecordData_len = 0; + res->recordIdentifier = 0; return res; } + +Z_SRW_record *yaz_srw_get_records(ODR o, int n) +{ + Z_SRW_record *res = (Z_SRW_record *) odr_malloc(o, n * sizeof(*res)); + int i; + + for (i = 0; iu.update_request)); sr->u.update_request->database = 0; sr->u.update_request->stylesheet = 0; - sr->u.update_request->record.recordSchema = 0; - sr->u.update_request->record.recordPacking = Z_SRW_recordPacking_XML; + sr->u.update_request->record = 0; sr->u.update_request->recordId = 0; - sr->u.update_request->recordVersion = 0; - sr->u.update_request->recordOldVersion = 0; - sr->u.update_request->record.recordData_buf = 0; - sr->u.update_request->record.recordData_len = 0; + sr->u.update_request->recordVersions = 0; + sr->u.update_request->num_recordVersions = 0; sr->u.update_request->extra_record = 0; - sr->u.update_request->extraRequestData = 0; + sr->u.update_request->extraRequestData_buf = 0; + sr->u.update_request->extraRequestData_len = 0; sr->u.request->database = 0; break; case Z_SRW_update_response: @@ -884,15 +897,12 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which) odr_malloc(o, sizeof(*sr->u.update_response)); sr->u.update_response->operationStatus = 0; sr->u.update_response->recordId = 0; - sr->u.update_response->recordVersion = 0; - sr->u.update_response->recordChecksum = 0; - sr->u.update_response->record.recordData_buf = 0; - sr->u.update_response->record.recordData_len = 0; - sr->u.update_response->record.recordSchema = 0; - sr->u.update_response->record.recordPacking = - Z_SRW_recordPacking_XML; + sr->u.update_response->recordVersions = 0; + sr->u.update_response->num_recordVersions = 0; + sr->u.update_response->record = 0; sr->u.update_response->extra_record = 0; - sr->u.update_response->extraResponseData = 0; + sr->u.update_response->extraResponseData_buf = 0; + sr->u.update_response->extraResponseData_len = 0; sr->u.update_response->diagnostics = 0; sr->u.update_response->num_diagnostics = 0; } @@ -1254,13 +1264,15 @@ int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, ODR odr, const char *charset) { - Z_SOAP_Handler handlers[2] = { + Z_SOAP_Handler handlers[3] = { #if YAZ_HAVE_XML2 - {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, #endif {0, 0, 0} }; Z_SOAP *p = (Z_SOAP*) odr_malloc(odr, sizeof(*p)); + z_HTTP_header_add_content_type(odr, &hreq->headers, "text/xml", charset); @@ -1273,13 +1285,55 @@ int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, p->u.generic->ns = 0; p->u.generic->p = srw_pdu; p->ns = "http://schemas.xmlsoap.org/soap/envelope/"; - + +#if YAZ_HAVE_XML2 + if (srw_pdu->which == Z_SRW_update_request || + srw_pdu->which == Z_SRW_update_response) + p->u.generic->no = 1; /* second handler */ +#endif return z_soap_codec_enc(odr, &p, &hreq->content_buf, &hreq->content_len, handlers, charset); } +Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR odr, int num ) +{ + Z_SRW_recordVersion *ver + = (Z_SRW_recordVersion *) odr_malloc( odr, num * sizeof(*ver) ); + int i; + for ( i=0; i < num; ++i ){ + ver[i].versionType = 0; + ver[i].versionValue = 0; + } + return ver; +} + +const char *yaz_srw_pack_to_str(int pack) +{ + switch(pack) + { + case Z_SRW_recordPacking_string: + return "string"; + case Z_SRW_recordPacking_XML: + return "xml"; + case Z_SRW_recordPacking_URL: + return "url"; + } + return 0; +} + +int yaz_srw_str_to_pack(const char *str) +{ + if (!strcmp(str, "string")) + return Z_SRW_recordPacking_string; + if (!strcmp(str, "xml")) + return Z_SRW_recordPacking_XML; + if (!strcmp(str, "url")) + return Z_SRW_recordPacking_URL; + return -1; +} + /* * Local variables: * c-basic-offset: 4 diff --git a/src/zoom-c.c b/src/zoom-c.c index 65d14ab..dd62ea7 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.101 2006-12-06 11:12:14 mike Exp $ + * $Id: zoom-c.c,v 1.102 2006-12-06 21:35:58 adam Exp $ */ /** * \file zoom-c.c @@ -1276,7 +1276,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c) odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName)); - version = odr_strdup(c->odr_out, "$Revision: 1.101 $"); + version = odr_strdup(c->odr_out, "$Revision: 1.102 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; ireq->implementationVersion = @@ -3688,8 +3688,7 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) Z_SOAP *soap_package = 0; ODR o = c->odr_in; Z_SOAP_Handler soap_handlers[2] = { - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; ret = z_soap_codec(o, &soap_package, diff --git a/ztest/ztest.c b/ztest/ztest.c index 515d1ac..77a600d 100644 --- a/ztest/ztest.c +++ b/ztest/ztest.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: ztest.c,v 1.82 2006-12-04 14:56:55 adam Exp $ + * $Id: ztest.c,v 1.83 2006-12-06 21:35:59 adam Exp $ */ /* @@ -673,6 +673,12 @@ int ztest_explain(void *handle, bend_explain_rr *rr) return 0; } +int ztest_update(void *handle, bend_update_rr *rr) +{ + rr->operation_status = "success"; + return 0; +} + bend_initresult *bend_init(bend_initrequest *q) { bend_initresult *r = (bend_initresult *) @@ -700,6 +706,7 @@ bend_initresult *bend_init(bend_initrequest *q) q->bend_explain = ztest_explain; #endif q->bend_srw_scan = ztest_scan; + q->bend_srw_update = ztest_update; return r; }