Happy new year
[yazpp-moved-to-github.git] / zlint / test-search-01.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) Index Data and Mike Taylor
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
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
63 Zlint_test_search_01::~Zlint_test_search_01()
64 {
65 }
66
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
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
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
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