From 66ed48c630abf19ec779a29c5d2b67a9938685a5 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 19 Nov 2009 13:24:45 +0100 Subject: [PATCH] Glob-pattern for virt_db match (bug #3106) --- NEWS | 3 +++ doc/virt_db.xml | 12 +++++++++- src/filter_virt_db.cpp | 62 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 18729ae..fa69a51 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +For filter virt_db, the database is a glob pattern and the virtual +database sections are consulted in the order given. + --- 1.0.19 2009/07/08 For filter multi, the target (for routing) may be given as a glob-pattern. diff --git a/doc/virt_db.xml b/doc/virt_db.xml index 1fbdf96..c0a305b 100644 --- a/doc/virt_db.xml +++ b/doc/virt_db.xml @@ -27,7 +27,13 @@ Z39.50 virtual database recognized. The name of the database is the text content of the <database> element which should be - first element inside th virtual section. + first element inside the virtual section. + + + For Metaproxy 1.0.20 and later, the database is treated as a glob pattern. + This allows operators * (any number of any character) and + ? (any single character). The virtual sections are inspected in + the order given. The first matching virtual database is used. Following that is one or more <target> @@ -74,6 +80,10 @@ db3 indexdata.com/special + + * + localhost:9999 + ]]> diff --git a/src/filter_virt_db.cpp b/src/filter_virt_db.cpp index 2b6a343..aca2634 100644 --- a/src/filter_virt_db.cpp +++ b/src/filter_virt_db.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include #include #include @@ -50,8 +51,10 @@ namespace metaproxy_1 { std::string m_setname; }; struct VirtualDB::Map { - Map(std::list targets, std::string route); + Map(std::string database, std::list targets, std::string route); Map(); + bool match(const std::string db) const; + std::string m_dbpattern; std::list m_targets; std::string m_route; }; @@ -105,7 +108,7 @@ namespace metaproxy_1 { FrontendPtr get_frontend(Package &package); void release_frontend(Package &package); private: - std::mapm_maps; + std::listm_maps; typedef std::map::iterator Sets_it; boost::mutex m_mutex; boost::condition m_cond_session_ready; @@ -142,8 +145,15 @@ yf::VirtualDB::BackendPtr yf::VirtualDB::Frontend::create_backend_from_databases std::map targets_dedup; for (; db_it != databases.end(); db_it++) { - std::map::iterator map_it; - map_it = m_p->m_maps.find(mp::util::database_name_normalize(*db_it)); + std::list::const_iterator map_it; + map_it = m_p->m_maps.begin(); + while (map_it != m_p->m_maps.end()) + { + if (map_it->match(*db_it)) + break; + map_it++; + } + if (map_it == m_p->m_maps.end()) // database not found { error_code = YAZ_BIB1_DATABASE_DOES_NOT_EXIST; @@ -152,8 +162,8 @@ yf::VirtualDB::BackendPtr yf::VirtualDB::Frontend::create_backend_from_databases return ptr; } std::list::const_iterator t_it = - map_it->second.m_targets.begin(); - for (; t_it != map_it->second.m_targets.end(); t_it++) { + map_it->m_targets.begin(); + for (; t_it != map_it->m_targets.end(); t_it++) { if (!targets_dedup[*t_it]) { targets_dedup[*t_it] = true; @@ -162,14 +172,14 @@ yf::VirtualDB::BackendPtr yf::VirtualDB::Frontend::create_backend_from_databases } // see if we have a route conflict. - if (!first_route && b->m_route != map_it->second.m_route) + if (!first_route && b->m_route != map_it->m_route) { // we have a conflict.. error_code = YAZ_BIB1_COMBI_OF_SPECIFIED_DATABASES_UNSUPP; BackendPtr ptr; return ptr; } - b->m_route = map_it->second.m_route; + b->m_route = map_it->m_route; first_route = false; } return b; @@ -462,8 +472,9 @@ yf::VirtualDB::Set::~Set() { } -yf::VirtualDB::Map::Map(std::list targets, std::string route) - : m_targets(targets), m_route(route) +yf::VirtualDB::Map::Map(std::string database, + std::list targets, std::string route) + : m_dbpattern(database), m_targets(targets), m_route(route) { } @@ -471,6 +482,14 @@ yf::VirtualDB::Map::Map() { } +bool yf::VirtualDB::Map::match(const std::string db) const +{ + std::string norm_db = mp::util::database_name_normalize(db); + if (yaz_match_glob(m_dbpattern.c_str(), norm_db.c_str())) + return true; + return false; +} + yf::VirtualDB::VirtualDB() : m_p(new VirtualDB::Rep) { m_p->pass_vhosts = false; @@ -492,21 +511,26 @@ void yf::VirtualDB::Frontend::fixup_npr_record(ODR odr, Z_NamePlusRecord *npr, db_it != b->m_frontend_databases.end(); db_it++) { // see which target it corresponds to.. (if any) - std::map::const_iterator map_it; - - map_it = m_p->m_maps.find(mp::util::database_name_normalize(*db_it)); + std::list::const_iterator map_it = + m_p->m_maps.begin(); + while (map_it != m_p->m_maps.end()) + { + if (map_it->match(*db_it)) + break; + map_it++; + } if (map_it != m_p->m_maps.end()) { - VirtualDB::Map m = map_it->second; - - std::list::const_iterator t; - for (t = m.m_targets.begin(); t != m.m_targets.end(); t++) + std::list::const_iterator t + = map_it->m_targets.begin(); + while (t != map_it->m_targets.end()) { if (*t == b_database) { npr->databaseName = odr_strdup(odr, (*db_it).c_str()); return; } + t++; } } @@ -670,8 +694,8 @@ void yf::VirtualDB::add_map_db2targets(std::string db, std::list targets, std::string route) { - m_p->m_maps[mp::util::database_name_normalize(db)] - = VirtualDB::Map(targets, route); + m_p->m_maps.push_back( + VirtualDB::Map(mp::util::database_name_normalize(db), targets, route)); } -- 1.7.10.4