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 #include <drizzled/util/find_ptr.h>
00036 
00037 #include <boost/bind.hpp>
00038 #include <boost/foreach.hpp>
00039 
00040 using namespace std;
00041 
00042 namespace drizzled {
00043 
00044 module::Registry::Registry() :
00045   module_registry_(),
00046   depend_graph_(new module::Graph()),
00047   plugin_registry(),
00048   deps_built_(false)
00049 { }
00050 
00051 
00052 module::Registry::~Registry()
00053 {
00054   /* Give all plugins a chance to cleanup, before
00055    * all plugins are deleted.
00056    * This can be used if shutdown code references
00057    * other plugins.
00058    */
00059   BOOST_FOREACH(plugin::Plugin::map::reference it, plugin_registry)
00060     it.second->shutdownPlugin();
00061 
00062   plugin::Plugin::vector error_plugins;
00063   BOOST_FOREACH(plugin::Plugin::map::reference it, plugin_registry)
00064   {
00065     if (it.second->removeLast())
00066       error_plugins.push_back(it.second);
00067     else
00068       delete it.second;
00069   }
00070 
00071   BOOST_FOREACH(plugin::Plugin::vector::reference it, error_plugins)
00072     delete it;
00073 
00074   plugin_registry.clear();
00075 
00076 #if 0
00077   /*
00078   @TODO When we delete modules here, we segfault on a bad string. Why?
00079    */
00080 
00081   BOOST_FOREACH(ModuleMap::reference it, module_registry_)
00082     delete it.second;
00083   module_registry_.clear();
00084 #endif
00085   BOOST_FOREACH(LibraryMap::reference it, library_registry_)
00086     delete it.second;
00087   library_registry_.clear();
00088 }
00089 
00090 void module::Registry::shutdown()
00091 {
00092   delete &singleton();
00093 }
00094 
00095 module::Module* module::Registry::find(const std::string& name)
00096 {
00097   return find_ptr2(module_registry_, boost::to_lower_copy(name));
00098 }
00099 
00100 void module::Registry::add(module::Module *handle)
00101 {
00102   std::string add_str(boost::to_lower_copy(handle->getName()));
00103 
00104   module_registry_[add_str]= handle;
00105 
00106   Vertex vertex_info(add_str, handle);
00107   VertexDesc handle_vertex= boost::add_vertex(depend_graph_->getGraph());
00108   depend_graph_->properties(handle_vertex)= vertex_info;
00109 
00110   handle->setVertexHandle(new VertexHandle(handle_vertex));
00111 }
00112 
00113 void module::Registry::remove(module::Module *handle)
00114 {
00115   module_registry_.erase(boost::to_lower_copy(handle->getName()));
00116 }
00117 
00118 void module::Registry::buildDeps()
00119 {
00120   BOOST_FOREACH(ModuleMap::reference map_iter, module_registry_)
00121   {
00122     Module* handle= map_iter.second;
00123     BOOST_FOREACH(Module::Depends::const_reference handle_deps, handle->getDepends())
00124     {
00125       std::string dep_str(boost::to_lower_copy(handle_deps));
00126       bool found_dep= false;
00127       for (vertex_iter it= boost::vertices(depend_graph_->getGraph()).first; it != vertices(depend_graph_->getGraph()).second; it++)
00128       {
00129         if (depend_graph_->properties(*it).getName() == dep_str)
00130         {
00131           found_dep= true;
00132           add_edge(handle->getVertexHandle()->getVertexDesc(), *it, depend_graph_->getGraph());
00133           break;
00134         }
00135       }
00136       if (not found_dep)
00137       {
00138         errmsg_printf(error::ERROR, _("Couldn't process plugin module dependencies. %s depends on %s but %s is not to be loaded.\n"),
00139           handle->getName().c_str(), dep_str.c_str(), dep_str.c_str());
00140         DRIZZLE_ABORT;
00141       }
00142     }
00143   }
00144   deps_built_= true;
00145 }
00146 
00147 module::Registry::ModuleList module::Registry::getList()
00148 {
00149   if (not deps_built_)
00150     buildDeps();
00151   VertexList vertex_list;
00152   boost::topological_sort(depend_graph_->getGraph(), std::back_inserter(vertex_list));
00153   ModuleList plugins;
00154   BOOST_FOREACH(VertexList::reference it, vertex_list)
00155   {
00156     if (Module* mod_ptr= depend_graph_->properties(it).getModule())
00157       plugins.push_back(mod_ptr);
00158   }
00159   return plugins;
00160 }
00161 
00162 module::Library *module::Registry::addLibrary(const std::string &plugin_name, bool builtin)
00163 {
00164   /* If this dll is already loaded just return it */
00165   module::Library *library= findLibrary(plugin_name);
00166   if (library)
00167     return library;
00168 
00169   library= module::Library::loadLibrary(plugin_name, builtin);
00170   if (library)
00171   {
00172     /* Add this dll to the map */
00173     library_registry_.insert(make_pair(plugin_name, library));
00174   }
00175   return library;
00176 }
00177 
00178 void module::Registry::removeLibrary(const std::string &plugin_name)
00179 {
00180   LibraryMap::iterator iter= library_registry_.find(plugin_name);
00181   if (iter != library_registry_.end())
00182   {
00183     delete iter->second;
00184     library_registry_.erase(iter);
00185   }
00186 }
00187 
00188 module::Library *module::Registry::findLibrary(const std::string &plugin_name) const
00189 {
00190   return find_ptr2(library_registry_, plugin_name);
00191 }
00192 
00193 void module::Registry::shutdownModules()
00194 {
00195   module_shutdown(*this);
00196 }
00197 
00198 } /* namespace drizzled */