Updates for yaz/ylog.h
[yazpp-moved-to-github.git] / zlint / test-search-01.cpp
1 /*
2  * Copyright (c) 2004, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: test-search-01.cpp,v 1.3 2004-11-30 21:10:31 adam Exp $
6  */
7
8 #include <yaz/ylog.h>
9 #include <yaz/pquery.h>
10 #include <yaz/sortspec.h>
11
12 #include <zlint.h>
13
14 static const char *try_query[] = {
15     "@attr 1=4 petersson",
16     "@attr 1=1016 petersson",
17     "@attr 1=4 kingdom",
18     "@attr 1=1016 kingdom",
19     "@attr 1=62 sword",
20     "sword"
21     "seven",
22     "@attr 1=4 water",
23     "@attr 1=1016 water",
24     "computer",
25     "@attr 1=4 computer",
26     "@attr 1=1016 computer",
27     "water",
28     "join",
29     "about",
30     "map",
31     0,
32 };
33
34 static const char *try_syntax [] = {
35     "usmarc",
36     "unimarc",
37     "danmarc",
38     "sutrs",
39     "grs1",
40     "xml",
41     "normarc",
42     0
43 };
44
45 static const char *try_sort [] = {
46     "1=4 <",
47     "1=4 >",
48     "1=62 >",
49     "1=62 <",
50     0
51 };
52
53 Zlint_test_search_01::Zlint_test_search_01()
54 {
55     m_query_no = 0;
56     m_record_syntax_no = 0;
57     m_got_result_set = 0;
58     m_sort_no = 0;
59 }
60
61 Zlint_test_search_01::~Zlint_test_search_01()
62 {
63 }
64
65 Zlint_code Zlint_test_search_01::init(Zlint *z)
66 {
67     int len;
68     Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
69     Z_InitRequest *init = apdu->u.initRequest;
70
71     z->msg_check_for("search and retrieve");
72
73     ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
74
75     ODR_MASK_SET(init->options, Z_Options_namedResultSets);
76     ODR_MASK_SET(init->options, Z_Options_sort);
77
78     int r = z->send_Z_PDU(apdu, &len);
79     if (r < 0)
80     {
81         z->msg_check_fail("unable to send init request");
82         return TEST_FINISHED;
83     }
84     return TEST_CONTINUE;
85 }
86
87 Zlint_code Zlint_test_search_01::sendTest(Zlint *z)
88 {
89     if (!m_got_result_set)
90     {
91         Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_searchRequest);
92         Z_SearchRequest *sr;
93         sr = apdu->u.searchRequest;
94         sr->query = (Z_Query *) odr_malloc(z->odr_encode(), sizeof(*sr->query));
95         if (try_query[m_query_no] && sr)
96         {
97             sr->query->which = Z_Query_type_1;
98             Z_RPNQuery *rpn;
99             YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
100             
101             z->getDatabase(&sr->databaseNames, &sr->num_databaseNames);
102             
103             rpn = yaz_pqf_parse(pqf_parser, z->odr_encode(),
104                                 try_query[m_query_no]);
105             
106             yaz_pqf_destroy (pqf_parser);
107             
108             if (!rpn)
109             {
110                 z->msg_check_fail("Query %s invalid", try_query[m_query_no]);
111                 return TEST_FINISHED;
112             }
113             int len;
114             sr->query->u.type_1 = rpn;
115             z->send_Z_PDU(apdu, &len);
116         }
117         else
118         {
119             z->msg_check_notapp();
120             z->msg_check_info("unable to get any hit count");
121             return TEST_FINISHED;
122         }
123     }
124     else if (m_got_result_set && try_syntax[m_record_syntax_no])
125     {
126         int len;
127         Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_presentRequest);
128         Z_PresentRequest *pr = apdu->u.presentRequest;
129         *pr->numberOfRecordsRequested = 1;
130         *pr->resultSetStartPoint = 1;
131
132         z->msg_check_for("record syntax %s", try_syntax[m_record_syntax_no]);
133         pr->preferredRecordSyntax =
134             yaz_str_to_z3950oid(z->odr_encode(), CLASS_RECSYN,
135                                 try_syntax[m_record_syntax_no]);
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 ver = z->initResponseGetVersion(init);
177         int result = init->result ? *init->result : 0;
178         if (!result)
179         {
180             z->msg_check_notapp();
181             z->msg_check_info ("init rejected (result false)");
182             return TEST_FINISHED;
183         }
184         return sendTest(z);
185     }
186     else if (gdu->which == Z_GDU_Z3950 &&
187              gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_searchResponse)
188     {
189         Z_SearchResponse *sr = gdu->u.z3950->u.searchResponse;
190         if (sr->records && (sr->records->which == Z_Records_NSD 
191                             || 
192                             sr->records->which == Z_Records_multipleNSD))
193             m_query_no++;
194         else if (!sr->resultCount || *sr->resultCount == 0)
195             m_query_no++;
196         else
197         {
198             z->msg_check_ok();
199             z->msg_check_info("got %d result count with %s", *sr->resultCount,
200                               try_query[m_query_no]);
201             m_got_result_set = 1;
202         }
203         return sendTest(z);
204     }
205     else if (gdu->which == Z_GDU_Z3950 && 
206              gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_presentResponse)
207     {
208         Z_PresentResponse *sr = gdu->u.z3950->u.presentResponse;
209         if (sr->records && (sr->records->which == Z_Records_NSD 
210                             || 
211                             sr->records->which == Z_Records_multipleNSD))
212         {
213             z->msg_check_ok();
214             z->msg_check_info("present returned NSD for %s",
215                               try_syntax[m_record_syntax_no]);
216         }
217         else if (sr->records && sr->records->which == Z_Records_DBOSD
218                  && sr->records->u.databaseOrSurDiagnostics->num_records>0
219                  && sr->records->u.databaseOrSurDiagnostics->records[0])
220         {
221             if (sr->records->u.databaseOrSurDiagnostics->records[0]->which == Z_NamePlusRecord_databaseRecord)
222             {
223                 Z_External *ext = sr->records->u.databaseOrSurDiagnostics->records[0]->u.databaseRecord;
224                 Odr_oid *expectRecordSyntax =
225                     yaz_str_to_z3950oid(z->odr_decode(), CLASS_RECSYN,
226                                         try_syntax[m_record_syntax_no]);
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 }