-/* $Id: filter_virt_db.cpp,v 1.36 2006-03-16 10:40:59 adam Exp $
+/* $Id: filter_virt_db.cpp,v 1.43 2006-07-06 13:55:42 adam Exp $
Copyright (c) 2005-2006, Index Data.
-%LICENSE%
+ See the LICENSE file for details
*/
#include "config.hpp"
void close(Package &package);
typedef std::map<std::string,Virt_db::Set>::iterator Sets_it;
+ void fixup_package(Package &p, BackendPtr b);
+ void fixup_npr_record(ODR odr, Z_NamePlusRecord *npr,
+ BackendPtr b);
+ void fixup_npr_records(ODR odr, Z_Records *records,
+ BackendPtr b);
+
BackendPtr lookup_backend_from_databases(
std::list<std::string> databases);
BackendPtr create_backend_from_databases(
FrontendPtr get_frontend(Package &package);
void release_frontend(Package &package);
private:
- boost::mutex m_sessions_mutex;
std::map<std::string, Virt_db::Map>m_maps;
-
typedef std::map<std::string,Virt_db::Set>::iterator Sets_it;
-
boost::mutex m_mutex;
boost::condition m_cond_session_ready;
std::map<mp::Session, FrontendPtr> m_clients;
}
}
-using namespace mp;
-
yf::Virt_db::BackendPtr yf::Virt_db::Frontend::lookup_backend_from_databases(
std::list<std::string> databases)
{
for (; db_it != databases.end(); db_it++)
{
std::map<std::string, Virt_db::Map>::iterator map_it;
- map_it = m_p->m_maps.find(*db_it);
+ map_it = m_p->m_maps.find(mp::util::database_name_normalize(*db_it));
if (map_it == m_p->m_maps.end()) // database not found
{
error_code = YAZ_BIB1_DATABASE_UNAVAILABLE;
}
yf::Virt_db::BackendPtr yf::Virt_db::Frontend::init_backend(
- std::list<std::string> databases, Package &package,
+ std::list<std::string> databases, mp::Package &package,
int &error_code, std::string &addinfo)
{
BackendPtr b = create_backend_from_databases(databases, error_code,
return b;
}
-void yf::Virt_db::Frontend::search(Package &package, Z_APDU *apdu_req)
+void yf::Virt_db::Frontend::search(mp::Package &package, Z_APDU *apdu_req)
{
Z_SearchRequest *req = apdu_req->u.searchRequest;
std::string vhost;
package.session().close();
return;
}
- package.response() = search_package.response();
-
b->m_number_of_sets++;
m_sets[resultSetId] = Virt_db::Set(b, backend_setname);
+ fixup_package(search_package, b);
+ package.response() = search_package.response();
}
yf::Virt_db::Frontend::Frontend(Rep *rep)
m_is_virtual = false;
}
-void yf::Virt_db::Frontend::close(Package &package)
+void yf::Virt_db::Frontend::close(mp::Package &package)
{
std::list<BackendPtr>::const_iterator b_it;
{
}
-yf::Virt_db::FrontendPtr yf::Virt_db::Rep::get_frontend(Package &package)
+yf::Virt_db::FrontendPtr yf::Virt_db::Rep::get_frontend(mp::Package &package)
{
boost::mutex::scoped_lock lock(m_mutex);
return f;
}
-void yf::Virt_db::Rep::release_frontend(Package &package)
+void yf::Virt_db::Rep::release_frontend(mp::Package &package)
{
boost::mutex::scoped_lock lock(m_mutex);
std::map<mp::Session,yf::Virt_db::FrontendPtr>::iterator it;
yf::Virt_db::~Virt_db() {
}
-void yf::Virt_db::Frontend::present(Package &package, Z_APDU *apdu_req)
+void yf::Virt_db::Frontend::fixup_npr_record(ODR odr, Z_NamePlusRecord *npr,
+ BackendPtr b)
+{
+ if (npr->databaseName)
+ {
+ std::string b_database = std::string(npr->databaseName);
+
+ std::cout << "Fix up: " << b_database << "\n";
+
+ // consider each of the frontend databases..
+ std::list<std::string>::const_iterator db_it;
+ for (db_it = b->m_frontend_databases.begin();
+ db_it != b->m_frontend_databases.end(); db_it++)
+ {
+ // see which target it corresponds to.. (if any)
+ std::map<std::string,Virt_db::Map>::const_iterator map_it;
+ map_it = m_p->m_maps.find(*db_it);
+ if (map_it != m_p->m_maps.end())
+ {
+ Virt_db::Map m = map_it->second;
+
+ std::list<std::string>::const_iterator t;
+ for (t = m.m_targets.begin(); t != m.m_targets.end(); t++)
+ {
+ if (*t == b_database)
+ {
+ npr->databaseName = odr_strdup(odr, (*db_it).c_str());
+ return;
+ }
+ }
+ }
+
+ }
+ db_it = b->m_frontend_databases.begin();
+ if (db_it != b->m_frontend_databases.end())
+ {
+ std::string database = *db_it;
+ npr->databaseName = odr_strdup(odr, database.c_str());
+ }
+ }
+}
+
+void yf::Virt_db::Frontend::fixup_npr_records(ODR odr, Z_Records *records,
+ BackendPtr b)
+{
+ if (records && records->which == Z_Records_DBOSD)
+ {
+ Z_NamePlusRecordList *nprlist = records->u.databaseOrSurDiagnostics;
+ int i;
+ for (i = 0; i < nprlist->num_records; i++)
+ {
+ fixup_npr_record(odr, nprlist->records[i], b);
+ }
+ }
+}
+
+void yf::Virt_db::Frontend::fixup_package(mp::Package &p, BackendPtr b)
+{
+ Z_GDU *gdu = p.response().get();
+ mp::odr odr;
+
+ if (gdu && gdu->which == Z_GDU_Z3950)
+ {
+ Z_APDU *apdu = gdu->u.z3950;
+ if (apdu->which == Z_APDU_presentResponse)
+ {
+ fixup_npr_records(odr, apdu->u.presentResponse->records, b);
+ p.response() = gdu;
+ }
+ else if (apdu->which == Z_APDU_searchResponse)
+ {
+ fixup_npr_records(odr, apdu->u.searchResponse->records, b);
+ p.response() = gdu;
+ }
+ }
+}
+
+void yf::Virt_db::Frontend::present(mp::Package &package, Z_APDU *apdu_req)
{
Z_PresentRequest *req = apdu_req->u.presentRequest;
std::string resultSetId = req->resultSetId;
present_package.move(sets_it->second.m_backend->m_route);
+ fixup_package(present_package, sets_it->second.m_backend);
+
if (present_package.session().is_closed())
{
package.response() = present_package.response();
delete id;
}
-void yf::Virt_db::Frontend::scan(Package &package, Z_APDU *apdu_req)
+void yf::Virt_db::Frontend::scan(mp::Package &package, Z_APDU *apdu_req)
{
Z_ScanRequest *req = apdu_req->u.scanRequest;
std::string vhost;
std::list<std::string> targets,
std::string route)
{
- m_p->m_maps[db] = Virt_db::Map(targets, route);
+ m_p->m_maps[mp::util::database_name_normalize(db)]
+ = Virt_db::Map(targets, route);
}
std::list<std::string> targets;
targets.push_back(target);
- m_p->m_maps[db] = Virt_db::Map(targets, route);
+ m_p->m_maps[mp::util::database_name_normalize(db)]
+ = Virt_db::Map(targets, route);
}
-void yf::Virt_db::process(Package &package) const
+void yf::Virt_db::process(mp::Package &package) const
{
FrontendPtr f = m_p->get_frontend(package);
{
f->scan(package, apdu);
}
+ else if (apdu->which == Z_APDU_close)
+ {
+ package.session().close();
+ }
else
{
mp::odr odr;