00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00056
00057
00058
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 ®istry;
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
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
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 }