Drizzled Public API Documentation

registry.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <string>
00023 #include <vector>
00024 #include <map>
00025 
00026 #include <drizzled/module/registry.h>
00027 #include <drizzled/module/library.h>
00028 #include <drizzled/module/graph.h>
00029 #include <drizzled/module/vertex_handle.h>
00030 
00031 #include <drizzled/plugin.h>
00032 #include <drizzled/show.h>
00033 #include <drizzled/cursor.h>
00034 #include <drizzled/abort_exception.h>
00035 
00036 #include <boost/bind.hpp>
00037 
00038 using namespace std;
00039 
00040 namespace drizzled
00041 {
00042 
00043 module::Registry::Registry() :
00044   module_registry_(),
00045   depend_graph_(new module::Graph()),
00046   plugin_registry(),
00047   deps_built_(false)
00048 { }
00049 
00050 
00051 module::Registry::~Registry()
00052 {
00053   plugin::Plugin::map::iterator plugin_iter;
00054 
00055   /* Give all plugins a chance to cleanup, before
00056    * all plugins are deleted.
00057    * This can be used if shutdown code references
00058    * other plugins.
00059    */
00060   plugin_iter= plugin_registry.begin();
00061   while (plugin_iter != plugin_registry.end())
00062   {
00063     (*plugin_iter).second->shutdownPlugin();
00064     ++plugin_iter;
00065   }
00066 
00067   plugin::Plugin::vector error_plugins;
00068   plugin_iter= plugin_registry.begin();
00069   while (plugin_iter != plugin_registry.end())
00070   {
00071     if ((*plugin_iter).second->removeLast())
00072     {
00073       error_plugins.push_back((*plugin_iter).second);
00074     }
00075     else
00076     {
00077       delete (*plugin_iter).second;
00078     }
00079     ++plugin_iter;
00080   }
00081 
00082   for (plugin::Plugin::vector::iterator iter= error_plugins.begin();
00083        iter != error_plugins.end(); iter++)
00084   {
00085     delete *iter;
00086   }
00087 
00088   plugin_registry.clear();
00089 
00090 #if 0
00091   @TODO When we delete modules here, we segfault on a bad string. Why?
00092    ModuleMap::iterator module_iter= module_registry_.begin();
00093 
00094   while (module_iter != module_registry_.end())
00095   {
00096     delete (*module_iter).second;
00097     ++module_iter;
00098   }
00099   module_registry_.clear();
00100 #endif
00101   LibraryMap::iterator library_iter= library_registry_.begin();
00102   while (library_iter != library_registry_.end())
00103   {
00104     delete (*library_iter).second;
00105     ++library_iter;
00106   }
00107   library_registry_.clear();
00108 }
00109 
00110 void module::Registry::shutdown()
00111 {
00112   module::Registry& registry= singleton();
00113   delete &registry;
00114 }
00115 
00116 module::Module *module::Registry::find(std::string name)
00117 {
00118   std::transform(name.begin(), name.end(), name.begin(), ::tolower);
00119 
00120   ModuleMap::iterator map_iter;
00121   map_iter= module_registry_.find(name);
00122   if (map_iter != module_registry_.end())
00123     return (*map_iter).second;
00124   return NULL;
00125 }
00126 
00127 void module::Registry::add(module::Module *handle)
00128 {
00129   std::string add_str(handle->getName());
00130   transform(add_str.begin(), add_str.end(),
00131             add_str.begin(), ::tolower);
00132 
00133   module_registry_[add_str]= handle;
00134 
00135   Vertex vertex_info(add_str, handle);
00136   VertexDesc handle_vertex= boost::add_vertex(depend_graph_->getGraph());
00137   depend_graph_->properties(handle_vertex)= vertex_info;
00138 
00139   handle->setVertexHandle(new VertexHandle(handle_vertex));
00140 
00141 }
00142 
00143 void module::Registry::remove(module::Module *handle)
00144 {
00145   std::string remove_str(handle->getName());
00146   std::transform(remove_str.begin(), remove_str.end(),
00147                  remove_str.begin(), ::tolower);
00148 
00149   module_registry_.erase(remove_str);
00150 }
00151 
00152 void module::Registry::copy(plugin::Plugin::vector &arg)
00153 {    
00154   arg.reserve(plugin_registry.size());
00155 
00156   std::transform(plugin_registry.begin(),
00157                  plugin_registry.end(),
00158                  std::back_inserter(arg),
00159                  boost::bind(&plugin::Plugin::map::value_type::second, _1) );
00160   assert(arg.size() == plugin_registry.size());
00161 }
00162 
00163 void module::Registry::buildDeps()
00164 {
00165   ModuleMap::iterator map_iter= module_registry_.begin();
00166   while (map_iter != module_registry_.end())
00167   {
00168     Module *handle= (*map_iter).second;
00169     Module::Depends::const_iterator handle_deps= handle->getDepends().begin();
00170     while (handle_deps != handle->getDepends().end())
00171     {
00172       std::string dep_str((*handle_deps));
00173       transform(dep_str.begin(), dep_str.end(),
00174                 dep_str.begin(), ::tolower);
00175 
00176       bool found_dep= false;
00177       vertex_iter it= boost::vertices(depend_graph_->getGraph()).first;
00178       while (it != vertices(depend_graph_->getGraph()).second)
00179       {
00180         if (depend_graph_->properties(*it).getName() == dep_str)
00181         {
00182           found_dep= true;
00183           add_edge(handle->getVertexHandle()->getVertexDesc(), *it, depend_graph_->getGraph());
00184           break;
00185         }
00186         ++it;
00187       }
00188       if (not found_dep)
00189       {
00190         errmsg_printf(error::ERROR,
00191                       _("Couldn't process plugin module dependencies. "
00192                         "%s depends on %s but %s is not to be loaded.\n"),
00193                       handle->getName().c_str(),
00194                       dep_str.c_str(), dep_str.c_str());
00195         DRIZZLE_ABORT;
00196       }
00197 
00198       ++handle_deps;
00199     }
00200     ++map_iter;
00201   }
00202   deps_built_= true;
00203 }
00204 
00205 module::Registry::ModuleList module::Registry::getList()
00206 {
00207   if (not deps_built_)
00208   {
00209     buildDeps();
00210   }
00211 
00212   std::vector<module::Module *> plugins;
00213 
00214   VertexList vertex_list;
00215 
00216   boost::topological_sort(depend_graph_->getGraph(), std::back_inserter(vertex_list));
00217 
00218   for (VertexList::iterator i = vertex_list.begin();
00219        i != vertex_list.end(); ++i)
00220   {
00221     Module *mod_ptr= depend_graph_->properties(*i).getModule();
00222     if (mod_ptr != NULL)
00223     {
00224       plugins.push_back(mod_ptr);
00225     }  
00226   }
00227 
00228   return plugins;
00229 }
00230 
00231 module::Library *module::Registry::addLibrary(const std::string &plugin_name,
00232                                               bool builtin)
00233 {
00234 
00235   /* If this dll is already loaded just return it */
00236   module::Library *library= findLibrary(plugin_name);
00237   if (library != NULL)
00238   {
00239     return library;
00240   }
00241 
00242   library= module::Library::loadLibrary(plugin_name, builtin);
00243   if (library != NULL)
00244   {
00245     /* Add this dll to the map */
00246     library_registry_.insert(make_pair(plugin_name, library));
00247   }
00248 
00249   return library;
00250 }
00251 
00252 void module::Registry::removeLibrary(const std::string &plugin_name)
00253 {
00254   std::map<std::string, module::Library *>::iterator iter=
00255     library_registry_.find(plugin_name);
00256   if (iter != library_registry_.end())
00257   {
00258     library_registry_.erase(iter);
00259     delete iter->second;
00260   }
00261 }
00262 
00263 module::Library *module::Registry::findLibrary(const std::string &plugin_name) const
00264 {
00265   LibraryMap::const_iterator iter= library_registry_.find(plugin_name);
00266   if (iter != library_registry_.end())
00267     return iter->second;
00268   return NULL;
00269 }
00270 
00271 void module::Registry::shutdownModules()
00272 {
00273   module_shutdown(*this);
00274 }
00275 
00276 } /* namespace drizzled */