YAZ
4.2.57
Main Page
Data Structures
Files
File List
Globals
src
zoom-sru.c
Go to the documentation of this file.
1
/* This file is part of the YAZ toolkit.
2
* Copyright (C) 1995-2013 Index Data
3
* See the file LICENSE for details.
4
*/
9
#if HAVE_CONFIG_H
10
#include <
config.h
>
11
#endif
12
13
#include <assert.h>
14
#include <string.h>
15
#include <
errno.h
>
16
#include "
zoom-p.h
"
17
18
#include <
yaz/log.h
>
19
#include <
yaz/pquery.h
>
20
21
#if YAZ_HAVE_XML2
22
static
void
set_SRU_error
(
ZOOM_connection
c,
Z_SRW_diagnostic
*d)
23
{
24
const
char
*uri = d->
uri
;
25
if
(uri)
26
ZOOM_set_dset_error
(c,
ZOOM_uri_to_code
(uri), uri, d->
details
, 0);
27
}
28
#endif
29
30
31
#if YAZ_HAVE_XML2
32
static
zoom_ret
send_srw
(
ZOOM_connection
c,
Z_SRW_PDU
*sr)
33
{
34
Z_GDU
*gdu;
35
const
char
*database =
ZOOM_options_get
(c->
options
,
"databaseName"
);
36
37
gdu =
z_get_HTTP_Request_uri
(c->
odr_out
, c->
host_port
,
38
database,
39
c->
proxy
? 1 : 0);
40
41
if
(c->
sru_mode
==
zoom_sru_get
)
42
{
43
yaz_sru_get_encode
(gdu->
u
.
HTTP_Request
, sr, c->
odr_out
, c->
charset
);
44
}
45
else
if
(c->
sru_mode
==
zoom_sru_post
)
46
{
47
yaz_sru_post_encode
(gdu->
u
.
HTTP_Request
, sr, c->
odr_out
, c->
charset
);
48
}
49
else
if
(c->
sru_mode
==
zoom_sru_soap
)
50
{
51
yaz_sru_soap_encode
(gdu->
u
.
HTTP_Request
, sr, c->
odr_out
, c->
charset
);
52
}
53
else
if
(c->
sru_mode
==
zoom_sru_solr
)
54
{
55
yaz_solr_encode_request
(gdu->
u
.
HTTP_Request
, sr, c->
odr_out
, c->
charset
);
56
}
57
return
ZOOM_send_GDU
(c, gdu);
58
}
59
#endif
60
61
#if YAZ_HAVE_XML2
62
static
Z_SRW_PDU
*
ZOOM_srw_get_pdu
(
ZOOM_connection
c,
int
type
)
63
{
64
Z_SRW_PDU
*sr =
yaz_srw_get_pdu
(c->
odr_out
, type, c->
sru_version
);
65
sr->
username
= c->
user
;
66
sr->
password
= c->
password
;
67
return
sr;
68
}
69
#endif
70
71
#if YAZ_HAVE_XML2
72
zoom_ret
ZOOM_connection_srw_send_scan
(
ZOOM_connection
c)
73
{
74
ZOOM_scanset
scan;
75
Z_SRW_PDU
*sr = 0;
76
const
char
*option_val = 0;
77
Z_Query
*z_query;
78
79
if
(!c->
tasks
)
80
return
zoom_complete
;
81
assert (c->
tasks
->
which
==
ZOOM_TASK_SCAN
);
82
scan = c->
tasks
->
u
.
scan
.scan;
83
84
sr =
ZOOM_srw_get_pdu
(c,
Z_SRW_scan_request
);
85
86
z_query =
ZOOM_query_get_Z_Query
(scan->
query
);
87
/* SRU scan can only carry CQL and PQF */
88
if
(z_query->
which
==
Z_Query_type_104
)
89
{
90
sr->
u
.
scan_request
->
query_type
=
Z_SRW_query_type_cql
;
91
sr->
u
.
scan_request
->
scanClause
.
cql
=
92
odr_strdup
(c->
odr_out
,
ZOOM_query_get_query_string
(scan->
query
));
93
}
94
else
if
(z_query->
which
==
Z_Query_type_1
95
|| z_query->
which
==
Z_Query_type_101
)
96
{
97
sr->
u
.
scan_request
->
query_type
=
Z_SRW_query_type_pqf
;
98
sr->
u
.
scan_request
->
scanClause
.
pqf
=
99
odr_strdup
(c->
odr_out
,
ZOOM_query_get_query_string
(scan->
query
));
100
}
101
else
102
{
103
ZOOM_set_error
(c,
ZOOM_ERROR_UNSUPPORTED_QUERY
, 0);
104
return
zoom_complete
;
105
}
106
107
sr->
u
.
scan_request
->
maximumTerms
=
odr_intdup
(
108
c->
odr_out
,
ZOOM_options_get_int
(scan->
options
,
"number"
, 10));
109
110
sr->
u
.
scan_request
->
responsePosition
=
odr_intdup
(
111
c->
odr_out
,
ZOOM_options_get_int
(scan->
options
,
"position"
, 1));
112
113
option_val =
ZOOM_options_get
(scan->
options
,
"extraArgs"
);
114
yaz_encode_sru_extra
(sr, c->
odr_out
, option_val);
115
return
send_srw
(c, sr);
116
}
117
#else
118
zoom_ret
ZOOM_connection_srw_send_scan
(
ZOOM_connection
c)
119
{
120
return
zoom_complete
;
121
}
122
#endif
123
124
#if YAZ_HAVE_XML2
125
zoom_ret
ZOOM_connection_srw_send_search
(
ZOOM_connection
c)
126
{
127
const
char
*facets = 0;
128
int
i;
129
int
*start, *count;
130
ZOOM_resultset
resultset = 0;
131
Z_SRW_PDU
*sr = 0;
132
const
char
*option_val = 0;
133
Z_Query
*z_query;
134
Z_FacetList
*facet_list = 0;
135
if
(c->
error
)
/* don't continue on error */
136
return
zoom_complete
;
137
assert(c->
tasks
);
138
switch
(c->
tasks
->
which
)
139
{
140
case
ZOOM_TASK_SEARCH
:
141
resultset = c->
tasks
->
u
.
search
.resultset;
142
if
(!resultset->
setname
)
143
resultset->
setname
=
xstrdup
(
"default"
);
144
ZOOM_options_set
(resultset->
options
,
"setname"
, resultset->
setname
);
145
start = &c->
tasks
->
u
.
search
.start;
146
count = &c->
tasks
->
u
.
search
.count;
147
facets =
ZOOM_options_get
(resultset->
options
,
"facets"
);
148
if
(facets)
149
facet_list =
yaz_pqf_parse_facet_list
(c->
odr_out
, facets);
150
break
;
151
case
ZOOM_TASK_RETRIEVE
:
152
resultset = c->
tasks
->
u
.
retrieve
.resultset;
153
154
start = &c->
tasks
->
u
.
retrieve
.start;
155
count = &c->
tasks
->
u
.
retrieve
.count;
156
157
if
(*start >= resultset->
size
)
158
return
zoom_complete
;
159
if
(*start + *count > resultset->
size
)
160
*count = resultset->
size
- *start;
161
162
for
(i = 0; i < *count; i++)
163
{
164
ZOOM_record
rec =
165
ZOOM_record_cache_lookup
(resultset, i + *start,
166
c->
tasks
->
u
.
retrieve
.syntax,
167
c->
tasks
->
u
.
retrieve
.elementSetName);
168
if
(!rec)
169
break
;
170
else
171
{
172
ZOOM_Event
event
=
ZOOM_Event_create
(
ZOOM_EVENT_RECV_RECORD
);
173
ZOOM_connection_put_event
(c, event);
174
}
175
}
176
*start += i;
177
*count -= i;
178
179
if
(*count == 0)
180
return
zoom_complete
;
181
break
;
182
default
:
183
return
zoom_complete
;
184
}
185
assert(resultset->
query
);
186
187
sr =
ZOOM_srw_get_pdu
(c,
Z_SRW_searchRetrieve_request
);
188
z_query =
ZOOM_query_get_Z_Query
(resultset->
query
);
189
190
if
(z_query->
which
==
Z_Query_type_104
191
&& z_query->
u
.
type_104
->
which
==
Z_External_CQL
)
192
{
193
sr->
u
.
request
->
query_type
=
Z_SRW_query_type_cql
;
194
sr->
u
.
request
->
query
.
cql
= z_query->
u
.
type_104
->
u
.
cql
;
195
}
196
else
if
(z_query->
which
==
Z_Query_type_1
&& z_query->
u
.
type_1
)
197
{
198
sr->
u
.
request
->
query_type
=
Z_SRW_query_type_pqf
;
199
sr->
u
.
request
->
query
.
pqf
=
200
odr_strdup
(c->
odr_out
,
201
ZOOM_query_get_query_string
(resultset->
query
));
202
}
203
else
204
{
205
ZOOM_set_error
(c,
ZOOM_ERROR_UNSUPPORTED_QUERY
, 0);
206
return
zoom_complete
;
207
}
208
209
option_val =
ZOOM_query_get_sru11
(resultset->
query
);
210
if
(option_val)
211
{
212
sr->
u
.
request
->
sort_type
=
Z_SRW_sort_type_sort
;
213
sr->
u
.
request
->
sort
.
sortKeys
=
odr_strdup
(c->
odr_out
, option_val);
214
}
215
sr->
u
.
request
->
startRecord
=
odr_intdup
(c->
odr_out
, *start + 1);
216
sr->
u
.
request
->
maximumRecords
=
odr_intdup
(
217
c->
odr_out
, (resultset->
step
> 0 && resultset->
step
< *count) ?
218
resultset->
step
: *count);
219
sr->
u
.
request
->
recordSchema
= resultset->
schema
;
220
sr->
u
.
request
->
facetList
= facet_list;
221
222
option_val =
ZOOM_resultset_option_get
(resultset,
"recordPacking"
);
223
if
(option_val)
224
sr->
u
.
request
->
recordPacking
=
odr_strdup
(c->
odr_out
, option_val);
225
226
option_val =
ZOOM_resultset_option_get
(resultset,
"extraArgs"
);
227
yaz_encode_sru_extra
(sr, c->
odr_out
, option_val);
228
return
send_srw
(c, sr);
229
}
230
#else
231
zoom_ret
ZOOM_connection_srw_send_search
(
ZOOM_connection
c)
232
{
233
return
zoom_complete
;
234
}
235
#endif
236
237
#if YAZ_HAVE_XML2
238
static
zoom_ret
handle_srw_response
(
ZOOM_connection
c,
239
Z_SRW_searchRetrieveResponse
*res)
240
{
241
ZOOM_resultset
resultset = 0;
242
int
i;
243
NMEM
nmem;
244
ZOOM_Event
event;
245
int
*start, *count;
246
const
char
*syntax, *elementSetName;
247
248
if
(!c->
tasks
)
249
return
zoom_complete
;
250
251
switch
(c->
tasks
->
which
)
252
{
253
case
ZOOM_TASK_SEARCH
:
254
resultset = c->
tasks
->
u
.
search
.resultset;
255
start = &c->
tasks
->
u
.
search
.start;
256
count = &c->
tasks
->
u
.
search
.count;
257
syntax = c->
tasks
->
u
.
search
.syntax;
258
elementSetName = c->
tasks
->
u
.
search
.elementSetName;
259
260
/* Required not for reporting client hit count multiple times into session */
261
if
(!c->
tasks
->
u
.
search
.recv_search_fired) {
262
yaz_log
(
YLOG_DEBUG
,
"posting ZOOM_EVENT_RECV_SEARCH"
);
263
event
=
ZOOM_Event_create
(
ZOOM_EVENT_RECV_SEARCH
);
264
ZOOM_connection_put_event
(c, event);
265
c->
tasks
->
u
.
search
.recv_search_fired = 1;
266
}
267
if
(res->
facetList
)
268
ZOOM_handle_facet_list
(resultset, res->
facetList
);
269
break
;
270
case
ZOOM_TASK_RETRIEVE
:
271
resultset = c->
tasks
->
u
.
retrieve
.resultset;
272
start = &c->
tasks
->
u
.
retrieve
.start;
273
count = &c->
tasks
->
u
.
retrieve
.count;
274
syntax = c->
tasks
->
u
.
retrieve
.syntax;
275
elementSetName = c->
tasks
->
u
.
retrieve
.elementSetName;
276
break
;
277
default
:
278
return
zoom_complete
;
279
}
280
281
resultset->
size
= 0;
282
283
if
(res->
resultSetId
)
284
ZOOM_resultset_option_set
(resultset,
"resultSetId"
, res->
resultSetId
);
285
286
yaz_log
(c->
log_details
,
"%p handle_srw_response got SRW response OK"
, c);
287
288
if
(res->
num_diagnostics
> 0)
289
{
290
set_SRU_error
(c, &res->
diagnostics
[0]);
291
}
292
else
293
{
294
if
(res->
numberOfRecords
) {
295
resultset->
size
= *res->
numberOfRecords
;
296
}
297
if
(res->
suggestions
) {
298
ZOOM_resultset_option_set
(resultset,
"suggestions"
, res->
suggestions
);
299
}
300
for
(i = 0; i<res->
num_records
; i++)
301
{
302
int
pos = *start + i;
303
Z_SRW_record
*sru_rec;
304
Z_SRW_diagnostic
*diag = 0;
305
int
num_diag;
306
307
Z_NamePlusRecord
*npr = (
Z_NamePlusRecord
*)
308
odr_malloc
(c->
odr_in
,
sizeof
(
Z_NamePlusRecord
));
309
310
/* only trust recordPosition if >= calculated position */
311
if
(res->
records
[i].
recordPosition
&&
312
*res->
records
[i].
recordPosition
>= pos + 1)
313
pos = *res->
records
[i].
recordPosition
- 1;
314
315
sru_rec = &res->
records
[i];
316
317
npr->
databaseName
= 0;
318
npr->
which
=
Z_NamePlusRecord_databaseRecord
;
319
npr->
u
.
databaseRecord
= (
Z_External
*)
320
odr_malloc
(c->
odr_in
,
sizeof
(
Z_External
));
321
npr->
u
.
databaseRecord
->
descriptor
= 0;
322
npr->
u
.
databaseRecord
->
direct_reference
=
323
odr_oiddup
(c->
odr_in
,
yaz_oid_recsyn_xml
);
324
npr->
u
.
databaseRecord
->
indirect_reference
= 0;
325
npr->
u
.
databaseRecord
->
which
=
Z_External_octet
;
326
327
npr->
u
.
databaseRecord
->
u
.
octet_aligned
= (
Odr_oct
*)
328
odr_malloc
(c->
odr_in
,
sizeof
(
Odr_oct
));
329
npr->
u
.
databaseRecord
->
u
.
octet_aligned
->
buf
= (
unsigned
char
*)
330
sru_rec->
recordData_buf
;
331
npr->
u
.
databaseRecord
->
u
.
octet_aligned
->
len
=
332
npr->
u
.
databaseRecord
->
u
.
octet_aligned
->
size
=
333
sru_rec->
recordData_len
;
334
335
if (sru_rec->
recordSchema
336
&& !strcmp(sru_rec->
recordSchema
,
337
"info:srw/schema/1/diagnostics-v1.1"
))
338
{
339
sru_decode_surrogate_diagnostics
(sru_rec->
recordData_buf
,
340
sru_rec->
recordData_len
,
341
&diag, &num_diag,
342
resultset->
odr
);
343
}
344
ZOOM_record_cache_add
(resultset, npr, pos, syntax, elementSetName,
345
sru_rec->
recordSchema
, diag);
346
}
347
*count -= i;
348
*start += i;
349
if
(*count + *start > resultset->
size
)
350
*count = resultset->
size
- *start;
351
yaz_log
(
YLOG_DEBUG
,
"SRU result set size "
ODR_INT_PRINTF
" start %d count %d"
, resultset->
size
, *start, *count);
352
if
(*count < 0)
353
*count = 0;
354
nmem =
odr_extract_mem
(c->
odr_in
);
355
nmem_transfer
(
odr_getmem
(resultset->
odr
), nmem);
356
nmem_destroy
(nmem);
357
358
if
(*count > 0)
359
return
ZOOM_connection_srw_send_search
(c);
360
}
361
return
zoom_complete
;
362
}
363
#endif
364
365
#if YAZ_HAVE_XML2
366
static
void
handle_srw_scan_response
(
ZOOM_connection
c,
367
Z_SRW_scanResponse
*res)
368
{
369
NMEM
nmem =
odr_extract_mem
(c->
odr_in
);
370
ZOOM_scanset
scan;
371
372
if
(!c->
tasks
|| c->
tasks
->
which
!=
ZOOM_TASK_SCAN
)
373
return
;
374
scan = c->
tasks
->
u
.
scan
.scan;
375
376
if
(res->
num_diagnostics
> 0)
377
set_SRU_error
(c, &res->
diagnostics
[0]);
378
379
scan->
scan_response
= 0;
380
scan->
srw_scan_response
= res;
381
nmem_transfer
(
odr_getmem
(scan->
odr
), nmem);
382
383
ZOOM_options_set_int
(scan->
options
,
"number"
, res->
num_terms
);
384
nmem_destroy
(nmem);
385
}
386
#endif
387
388
int
ZOOM_handle_sru
(
ZOOM_connection
c,
Z_HTTP_Response
*hres,
389
zoom_ret
*cret,
char
**addinfo)
390
{
391
#if YAZ_HAVE_XML2
392
int
ret = 0;
393
394
/* not redirect (normal response) */
395
if
(!
yaz_srw_check_content_type
(hres))
396
{
397
*addinfo =
"content-type"
;
398
ret = -1;
399
}
400
else
if
(c->
sru_mode
==
zoom_sru_solr
)
401
{
402
Z_SRW_PDU
*sr;
403
ret =
yaz_solr_decode_response
(c->
odr_in
, hres, &sr);
404
if
(ret == 0)
405
{
406
if
(sr->
which
==
Z_SRW_searchRetrieve_response
)
407
*cret =
handle_srw_response
(c, sr->
u
.
response
);
408
else
if
(sr->
which
==
Z_SRW_scan_response
)
409
handle_srw_scan_response
(c, sr->
u
.
scan_response
);
410
}
411
}
412
else
413
{
414
Z_SOAP
*soap_package = 0;
415
ODR
o = c->
odr_in
;
416
Z_SOAP_Handler
soap_handlers[3] = {
417
{
YAZ_XMLNS_SRU_v1_response
, 0, (
Z_SOAP_fun
)
yaz_srw_codec
},
418
{
YAZ_XMLNS_SRU_v2_response
, 0, (
Z_SOAP_fun
)
yaz_srw_codec
},
419
{0, 0, 0}
420
};
421
ret =
z_soap_codec
(o, &soap_package,
422
&hres->
content_buf
, &hres->
content_len
,
423
soap_handlers);
424
if
(!ret && soap_package->
which
==
Z_SOAP_generic
)
425
{
426
Z_SRW_PDU
*sr = (
Z_SRW_PDU
*) soap_package->
u
.
generic
->
p
;
427
428
ZOOM_options_set
(c->
options
,
"sru_version"
, sr->
srw_version
);
429
ZOOM_options_setl
(c->
options
,
"sru_extra_response_data"
,
430
sr->
extraResponseData_buf
, sr->
extraResponseData_len
);
431
if
(sr->
which
==
Z_SRW_searchRetrieve_response
)
432
*cret =
handle_srw_response
(c, sr->
u
.
response
);
433
else
if
(sr->
which
==
Z_SRW_scan_response
)
434
handle_srw_scan_response
(c, sr->
u
.
scan_response
);
435
else
436
ret = -1;
437
}
438
else
if
(!ret && (soap_package->
which
==
Z_SOAP_fault
439
|| soap_package->
which
==
Z_SOAP_error
))
440
{
441
ZOOM_set_HTTP_error
(c, hres->
code
,
442
soap_package->
u
.
fault
->
fault_code
,
443
soap_package->
u
.
fault
->
fault_string
);
444
}
445
else
446
{
447
size_t
max_chars = 1000;
448
size_t
sz = hres->
content_len
;
449
if
(sz > max_chars - 1)
450
sz = max_chars;
451
*addinfo =
odr_malloc
(c->
odr_in
, sz + 4);
452
memcpy(*addinfo, hres->
content_buf
, sz);
453
if
(sz == max_chars)
454
strcpy(*addinfo + sz,
"..."
);
455
else
456
strcpy(*addinfo + sz,
""
);
457
ret = -1;
458
}
459
}
460
return
ret;
461
#else
462
return
-1;
463
#endif
464
}
465
466
/*
467
* Local variables:
468
* c-basic-offset: 4
469
* c-file-style: "Stroustrup"
470
* indent-tabs-mode: nil
471
* End:
472
* vim: shiftwidth=4 tabstop=8 expandtab
473
*/
474
Generated on Wed May 15 2013 14:55:31 for YAZ by
1.8.1.2