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