1 /* $Id: p2_msg.cpp,v 1.2 2005-10-06 19:33:58 adam Exp $
2 Copyright (c) 1998-2005, Index Data.
4 This file is part of the yaz-proxy.
6 YAZ proxy is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 YAZ proxy is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with YAZ proxy; see the file LICENSE. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include <yaz/diagbib1.h>
24 #include "p2_backend.h"
25 #include "p2_frontend.h"
26 #include "p2_config.h"
27 #include "p2_modules.h"
29 using namespace yazpp_1;
32 IP2_BackendSet::~IP2_BackendSet()
36 IP2_Backend::~IP2_Backend()
41 P2_Backend::P2_Backend(P2_ConfigTarget *cfg, IP2_Backend *backend_int)
43 m_configTarget = new P2_ConfigTarget;
44 *m_configTarget = *cfg;
49 P2_Backend::~P2_Backend()
51 delete m_configTarget;
54 P2_BackendResultSet::P2_BackendResultSet()
59 P2_BackendResultSet::~P2_BackendResultSet()
64 P2_Backend *P2_Msg::select_backend(string db,
66 P2_BackendResultSet **bset)
68 P2_Config *cfg = m_server->lockConfig();
70 // see if some target has done this query before
73 P2_Backend *backend = 0;
75 list<P2_Backend *>::const_iterator it;
76 for (it = m_server->m_backend_list.begin();
77 it != m_server->m_backend_list.end(); it++)
82 if (db != (*it)->m_configTarget->m_virt_database)
88 list<P2_BackendResultSet *>::const_iterator is;
89 for (is = (*it)->m_resultSets.begin();
90 is != (*it)->m_resultSets.end(); is++)
92 if (query->match(&(*is)->m_query))
104 P2_ConfigTarget *target_cfg = cfg->find_target(db);
108 yaz_log(YLOG_WARN, "No backend for database %s",
113 P2_ModuleInterface0 *int0 =
114 reinterpret_cast<P2_ModuleInterface0 *>
115 (m_server->m_modules->get_interface(target_cfg->m_type.c_str(),
117 IP2_Backend *bint = 0;
120 bint = int0->create(target_cfg->m_target_address.c_str());
123 backend = new P2_Backend(target_cfg, bint);
126 m_server->m_backend_list.push_back(backend);
130 backend->m_busy = true;
131 m_server->unlockConfig();
135 void P2_FrontResultSet::setQuery(Z_Query *z_query)
137 m_query.set_Z_Query(z_query);
140 void P2_FrontResultSet::setDatabases(char **db, int num)
145 for (i = 0; i<num; i++)
146 m_db_list.push_back(db[i]);
149 P2_FrontResultSet::P2_FrontResultSet(const char *id)
155 P2_FrontResultSet::~P2_FrontResultSet()
159 P2_Msg::P2_Msg(GDU *gdu, P2_Frontend *front, P2_Server *server)
174 Z_APDU *P2_Msg::frontend_search_resultset(Z_APDU *z_gdu, ODR odr,
175 P2_FrontResultSet **rset)
177 Z_SearchRequest *req = z_gdu->u.searchRequest;
178 list<P2_FrontResultSet *>::iterator it;
179 P2_FrontResultSet *s = 0;
181 string id = req->resultSetName;
182 for (it = m_front->m_resultSets.begin(); it != m_front->m_resultSets.end(); it++)
184 if ((*it)->m_resultSetId == id)
192 // result set already exists
194 if (req->replaceIndicator && *req->replaceIndicator)
195 { // replace indicator true
196 s->setQuery(req->query);
197 s->setDatabases(req->databaseNames, req->num_databaseNames);
200 Z_APDU *apdu = zget_APDU(odr, Z_APDU_searchResponse);
201 Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records));
202 apdu->u.searchResponse->records = rec;
203 rec->which = Z_Records_NSD;
204 rec->u.nonSurrogateDiagnostic =
205 zget_DefaultDiagFormat(
206 odr, YAZ_BIB1_RESULT_SET_EXISTS_AND_REPLACE_INDICATOR_OFF,
212 s = new P2_FrontResultSet(req->resultSetName);
213 s->setQuery(req->query);
214 s->setDatabases(req->databaseNames, req->num_databaseNames);
215 m_front->m_resultSets.push_back(s);
220 Z_APDU *P2_Msg::frontend_search_apdu(Z_APDU *request_apdu, ODR odr)
222 P2_FrontResultSet *rset;
223 Z_APDU *response_apdu = frontend_search_resultset(request_apdu, odr,
226 return response_apdu;
228 // no immediate error (yet)
230 for (i = 0; i<rset->m_db_list.size(); i++)
232 string db = rset->m_db_list[i];
233 P2_BackendResultSet *bset;
234 P2_Backend *b = select_backend(db, &rset->m_query, &bset);
237 Z_APDU *apdu = zget_APDU(odr, Z_APDU_searchResponse);
238 Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records));
239 apdu->u.searchResponse->records = rec;
240 rec->which = Z_Records_NSD;
241 rec->u.nonSurrogateDiagnostic =
242 zget_DefaultDiagFormat(
243 odr, YAZ_BIB1_DATABASE_UNAVAILABLE, db.c_str());
248 bset = new P2_BackendResultSet();
250 bset->m_query.set_Z_Query(request_apdu->u.searchRequest->query);
251 bset->m_db_list.push_back(db);
253 b->m_int->search(&bset->m_query, &bset->m_int, &bset->m_hit_count);
254 b->m_resultSets.push_back(bset);
258 bset->m_int->get(1, 1);
260 response_apdu = zget_APDU(odr, Z_APDU_searchResponse);
261 *response_apdu->u.searchResponse->resultCount = bset->m_hit_count;
266 Z_APDU *apdu = zget_APDU(odr, Z_APDU_searchResponse);
267 Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records));
268 apdu->u.searchResponse->records = rec;
269 rec->which = Z_Records_NSD;
270 rec->u.nonSurrogateDiagnostic =
271 zget_DefaultDiagFormat(odr, YAZ_BIB1_UNSUPP_SEARCH, 0);
274 return response_apdu;
277 Z_APDU *P2_Msg::frontend_present_resultset(Z_APDU *z_gdu, ODR odr,
278 P2_FrontResultSet **rset)
280 Z_PresentRequest *req = z_gdu->u.presentRequest;
281 list<P2_FrontResultSet *>::iterator it;
282 P2_FrontResultSet *s = 0;
284 string id = req->resultSetId;
285 for (it = m_front->m_resultSets.begin(); it != m_front->m_resultSets.end(); it++)
287 if ((*it)->m_resultSetId == id)
295 return 0; // fine result set exists
297 Z_APDU *apdu = zget_APDU(odr, Z_APDU_presentResponse);
299 Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records));
300 apdu->u.presentResponse->records = rec;
301 rec->which = Z_Records_NSD;
302 rec->u.nonSurrogateDiagnostic =
303 zget_DefaultDiagFormat(
305 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
310 Z_APDU *P2_Msg::frontend_present_apdu(Z_APDU *request_apdu, ODR odr)
312 P2_FrontResultSet *rset;
313 Z_APDU *response_apdu = frontend_present_resultset(request_apdu, odr,
316 return response_apdu;
317 return zget_APDU(odr, Z_APDU_presentResponse);
320 IThreadPoolMsg *P2_Msg::handle()
322 ODR odr = odr_createmem(ODR_ENCODE);
323 yaz_log(YLOG_LOG, "P2_Msg:handle begin");
324 Z_GDU *request_gdu = m_gdu->get();
326 if (request_gdu->which == Z_GDU_Z3950)
328 Z_APDU *request_apdu = request_gdu->u.z3950;
329 Z_APDU *response_apdu = 0;
330 switch(request_apdu->which)
332 case Z_APDU_initRequest:
333 response_apdu = zget_APDU(odr, Z_APDU_initResponse);
334 ODR_MASK_SET(response_apdu->u.initResponse->options, Z_Options_triggerResourceCtrl);
335 ODR_MASK_SET(response_apdu->u.initResponse->options, Z_Options_search);
336 ODR_MASK_SET(response_apdu->u.initResponse->options, Z_Options_present);
337 ODR_MASK_SET(response_apdu->u.initResponse->options, Z_Options_namedResultSets);
339 case Z_APDU_searchRequest:
340 response_apdu = frontend_search_apdu(request_apdu, odr);
342 case Z_APDU_presentRequest:
343 response_apdu = frontend_present_apdu(request_apdu, odr);
345 case Z_APDU_triggerResourceControlRequest:
348 response_apdu = zget_APDU(odr, Z_APDU_close);
353 m_output = new GDU(response_apdu);
355 yaz_log(YLOG_LOG, "P2_Msg:handle end");
360 void P2_Msg::result()
362 m_front->m_no_requests--;
363 if (!m_front->m_delete_flag)
368 m_front->send_GDU(m_output->get(), &len);
373 m_front->m_delete_flag = 1;
376 if (m_front->m_delete_flag && m_front->m_no_requests == 0)
384 * indent-tabs-mode: nil
386 * vim: shiftwidth=4 tabstop=8 expandtab