+ return;
+ }
+ sets_it->second.m_backend->m_number_of_sets--;
+ }
+ // pick up any existing database with named result sets ..
+ // or one which has no result sets.. yet.
+ BackendPtr b; // null for now
+ std::list<BackendPtr>::const_iterator map_it;
+ map_it = m_backend_list.begin();
+ for (; map_it != m_backend_list.end(); map_it++)
+ {
+ BackendPtr tmp = *map_it;
+ if (tmp->m_frontend_databases == databases &&
+ (tmp->m_named_result_sets ||
+ tmp->m_number_of_sets == 0))
+ {
+ b = *map_it;
+ break;
+ }
+ }
+ if (!b) // no backend yet. Must create a new one
+ {
+ int error_code;
+ std::string addinfo;
+ b = init_backend(databases, package, error_code, addinfo);
+ if (!b)
+ {
+ // did not get a backend (unavailable somehow?)
+
+ Z_APDU *apdu =
+ odr.create_searchResponse(
+ apdu_req, error_code, addinfo.c_str());
+ package.response() = apdu;
+ return;
+ }
+ }
+ m_sets.erase(req->resultSetName);
+ // sending search to backend
+ Package search_package(b->m_backend_session, package.origin());
+
+ search_package.copy_filter(package);
+
+ std::string backend_setname;
+ if (b->m_named_result_sets)
+ {
+ backend_setname = std::string(req->resultSetName);
+ }
+ else
+ {
+ backend_setname = "default";
+ req->resultSetName = odr_strdup(odr, backend_setname.c_str());
+ }
+
+ // pick first targets spec and move the databases from it ..
+ std::list<std::string>::const_iterator t_it = b->m_targets.begin();
+ if (t_it != b->m_targets.end())
+ {
+ mp::util::set_databases_from_zurl(odr, *t_it,
+ &req->num_databaseNames,
+ &req->databaseNames);
+ }
+
+ *req->replaceIndicator = 1;
+
+ search_package.request() = ngdu;
+
+ search_package.move(b->m_route);
+
+ if (search_package.session().is_closed())
+ {
+ package.response() = search_package.response();
+ package.session().close();
+ return;
+ }
+
+ Z_GDU *gdu = search_package.response().get();
+ if (gdu && gdu->which == Z_GDU_Z3950
+ && gdu->u.z3950->which == Z_APDU_searchResponse)
+ {
+ Z_SearchResponse *b_resp = gdu->u.z3950->u.searchResponse;
+ Z_Records *z_records = b_resp->records;
+ if (!z_records || (z_records && z_records->which == Z_Records_DBOSD))
+ {
+ b->m_number_of_sets++;
+ m_sets[resultSetId] = VirtualDB::Set(b, backend_setname);
+ fixup_package(search_package, b);
+ }
+ }
+ package.response() = search_package.response();
+}
+
+yf::VirtualDB::Frontend::Frontend(Rep *rep)
+{
+ m_p = rep;
+ m_is_virtual = false;
+}
+
+void yf::VirtualDB::Frontend::close(mp::Package &package)
+{
+ std::list<BackendPtr>::const_iterator b_it;
+
+ for (b_it = m_backend_list.begin(); b_it != m_backend_list.end(); b_it++)
+ {
+ (*b_it)->m_backend_session.close();
+ Package close_package((*b_it)->m_backend_session, package.origin());
+ close_package.copy_filter(package);
+ close_package.move((*b_it)->m_route);
+ }
+ m_backend_list.clear();
+}
+
+yf::VirtualDB::Frontend::~Frontend()