1 /* This file is part of the yazpp toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
5
6 #if HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 #include <yaz/log.h>
10 #include <yaz/pquery.h>
11 #include <yaz/sortspec.h>
12
13 #include <zlint.h>
14 #include <yaz/oid_db.h>
15
16 static const char *try_query[] = {
17 "@attr 1=4 petersson",
18 "@attr 1=1016 petersson",
19 "@attr 1=4 kingdom",
20 "@attr 1=1016 kingdom",
21 "@attr 1=62 sword",
22 "sword"
23 "seven",
24 "@attr 1=4 water",
25 "@attr 1=1016 water",
26 "computer",
27 "@attr 1=4 computer",
28 "@attr 1=1016 computer",
29 "water",
30 "join",
31 "about",
32 "map",
33 0,
34 };
35
36 static const char *try_syntax [] = {
37 "usmarc",
38 "unimarc",
39 "danmarc",
40 "sutrs",
41 "grs1",
42 "xml",
43 "normarc",
44 0
45 };
46
47 static const char *try_sort [] = {
48 "1=4 <",
49 "1=4 >",
50 "1=62 >",
51 "1=62 <",
52 0
53 };
54
Zlint_test_search_01()55 Zlint_test_search_01::Zlint_test_search_01()
56 {
57 m_query_no = 0;
58 m_record_syntax_no = 0;
59 m_got_result_set = 0;
60 m_sort_no = 0;
61 }
62
~Zlint_test_search_01()63 Zlint_test_search_01::~Zlint_test_search_01()
64 {
65 }
66
init(Zlint * z)67 Zlint_code Zlint_test_search_01::init(Zlint *z)
68 {
69 int len;
70 Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
71 Z_InitRequest *init = apdu->u.initRequest;
72
73 z->msg_check_for("search and retrieve");
74
75 ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
76
77 ODR_MASK_SET(init->options, Z_Options_namedResultSets);
78 ODR_MASK_SET(init->options, Z_Options_sort);
79
80 int r = z->send_Z_PDU(apdu, &len);
81 if (r < 0)
82 {
83 z->msg_check_fail("unable to send init request");
84 return TEST_FINISHED;
85 }
86 return TEST_CONTINUE;
87 }
88
sendTest(Zlint * z)89 Zlint_code Zlint_test_search_01::sendTest(Zlint *z)
90 {
91 if (!m_got_result_set)
92 {
93 Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_searchRequest);
94 Z_SearchRequest *sr;
95 sr = apdu->u.searchRequest;
96 sr->query = (Z_Query *) odr_malloc(z->odr_encode(), sizeof(*sr->query));
97 if (try_query[m_query_no] && sr)
98 {
99 sr->query->which = Z_Query_type_1;
100 Z_RPNQuery *rpn;
101 YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
102
103 z->getDatabase(&sr->databaseNames, &sr->num_databaseNames);
104
105 rpn = yaz_pqf_parse(pqf_parser, z->odr_encode(),
106 try_query[m_query_no]);
107
108 yaz_pqf_destroy (pqf_parser);
109
110 if (!rpn)
111 {
112 z->msg_check_fail("Query %s invalid", try_query[m_query_no]);
113 return TEST_FINISHED;
114 }
115 int len;
116 sr->query->u.type_1 = rpn;
117 z->send_Z_PDU(apdu, &len);
118 }
119 else
120 {
121 z->msg_check_notapp();
122 z->msg_check_info("unable to get any hit count");
123 return TEST_FINISHED;
124 }
125 }
126 else if (m_got_result_set && try_syntax[m_record_syntax_no])
127 {
128 int len;
129 Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_presentRequest);
130 Z_PresentRequest *pr = apdu->u.presentRequest;
131 *pr->numberOfRecordsRequested = 1;
132 *pr->resultSetStartPoint = 1;
133
134 z->msg_check_for("record syntax %s", try_syntax[m_record_syntax_no]);
135 pr->preferredRecordSyntax =
136 yaz_string_to_oid_odr(yaz_oid_std(),
137 CLASS_RECSYN, try_syntax[m_record_syntax_no],
138 z->odr_encode());
139 z->send_Z_PDU(apdu, &len);
140 return TEST_CONTINUE;
141 }
142 else if(m_got_result_set && !try_syntax[m_record_syntax_no])
143 {
144 Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_sortRequest);
145 if (apdu && try_sort[m_sort_no])
146 {
147 z->msg_check_for("sort %s", try_sort[m_sort_no]);
148
149 const char *setstring = "default";
150 int len;
151 Z_SortRequest *sr = apdu->u.sortRequest;
152
153 sr->num_inputResultSetNames = 1;
154 sr->num_inputResultSetNames = 1;
155 sr->inputResultSetNames = (Z_InternationalString **)
156 odr_malloc (z->odr_encode(), sizeof(*sr->inputResultSetNames));
157 sr->inputResultSetNames[0] = odr_strdup (z->odr_encode(), setstring);
158 sr->sortedResultSetName = odr_strdup(z->odr_encode(), setstring);
159 sr->sortSequence = yaz_sort_spec(z->odr_encode(), try_sort[m_sort_no]);
160 z->send_Z_PDU(apdu, &len);
161 }
162 else
163 return TEST_FINISHED;
164 }
165 else
166 {
167 printf ("finished...\n");
168 return TEST_FINISHED;
169 }
170 return TEST_CONTINUE;
171 }
172
recv_gdu(Zlint * z,Z_GDU * gdu)173 Zlint_code Zlint_test_search_01::recv_gdu(Zlint *z, Z_GDU *gdu)
174 {
175 if (gdu->which == Z_GDU_Z3950 &&
176 gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_initResponse)
177 {
178 Z_InitResponse *init = gdu->u.z3950->u.initResponse;
179 int result = init->result ? *init->result : 0;
180 if (!result)
181 {
182 z->msg_check_notapp();
183 z->msg_check_info ("init rejected (result false)");
184 return TEST_FINISHED;
185 }
186 return sendTest(z);
187 }
188 else if (gdu->which == Z_GDU_Z3950 &&
189 gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_searchResponse)
190 {
191 Z_SearchResponse *sr = gdu->u.z3950->u.searchResponse;
192 if (sr->records && (sr->records->which == Z_Records_NSD
193 ||
194 sr->records->which == Z_Records_multipleNSD))
195 m_query_no++;
196 else if (!sr->resultCount || *sr->resultCount == 0)
197 m_query_no++;
198 else
199 {
200 z->msg_check_ok();
201 z->msg_check_info("got %d result count with %s", *sr->resultCount,
202 try_query[m_query_no]);
203 m_got_result_set = 1;
204 }
205 return sendTest(z);
206 }
207 else if (gdu->which == Z_GDU_Z3950 &&
208 gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_presentResponse)
209 {
210 Z_PresentResponse *sr = gdu->u.z3950->u.presentResponse;
211 if (sr->records && (sr->records->which == Z_Records_NSD
212 ||
213 sr->records->which == Z_Records_multipleNSD))
214 {
215 z->msg_check_ok();
216 z->msg_check_info("present returned NSD for %s",
217 try_syntax[m_record_syntax_no]);
218 }
219 else if (sr->records && sr->records->which == Z_Records_DBOSD
220 && sr->records->u.databaseOrSurDiagnostics->num_records>0
221 && sr->records->u.databaseOrSurDiagnostics->records[0])
222 {
223 if (sr->records->u.databaseOrSurDiagnostics->records[0]->which == Z_NamePlusRecord_databaseRecord)
224 {
225 Z_External *ext = sr->records->u.databaseOrSurDiagnostics->records[0]->u.databaseRecord;
226 Odr_oid *expectRecordSyntax =
227 yaz_string_to_oid_odr(
228 yaz_oid_std(), CLASS_RECSYN,
229 try_syntax[m_record_syntax_no], z->odr_decode());
230 if (oid_oidcmp(expectRecordSyntax,
231 ext->direct_reference))
232 {
233 z->msg_check_fail("Got Record in different syntax "
234 "from that requested %s",
235 try_syntax[m_record_syntax_no]);
236 }
237 else
238 z->msg_check_ok();
239 }
240 else if (sr->records->u.databaseOrSurDiagnostics->records[0]->which == Z_NamePlusRecord_surrogateDiagnostic)
241 {
242 z->msg_check_ok();
243 z->msg_check_info("present returned SD %s",
244 try_syntax[m_record_syntax_no]);
245 }
246 else
247 {
248 z->msg_check_ok();
249 z->msg_check_info("present returned fragment %s",
250 try_syntax[m_record_syntax_no]);
251 }
252 }
253 else
254 {
255 z->msg_check_fail("present returned no records or diagnostics");
256 }
257 m_record_syntax_no++;
258 return sendTest(z);
259 }
260 else if (gdu->which == Z_GDU_Z3950 &&
261 gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_sortResponse)
262 {
263 Z_SortResponse *sr = gdu->u.z3950->u.sortResponse;
264 z->msg_check_ok();
265 if (sr->diagnostics)
266 z->msg_check_info( "sort NSD for %s", try_sort[m_sort_no]);
267 m_sort_no++;
268 return sendTest(z);
269 }
270 else
271 z->msg_check_fail("did not receive init/search/present response "
272 "as expected");
273 return TEST_FINISHED;
274 }
275
recv_fail(Zlint * z,int reason)276 Zlint_code Zlint_test_search_01::recv_fail(Zlint *z, int reason)
277 {
278 z->msg_check_fail("target closed connection");
279 return TEST_FINISHED;
280 }
281 /*
282 * Local variables:
283 * c-basic-offset: 4
284 * c-file-style: "Stroustrup"
285 * indent-tabs-mode: nil
286 * End:
287 * vim: shiftwidth=4 tabstop=8 expandtab
288 */
289
290