Drizzled Public API Documentation

registry.cc
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include <config.h>
21 
22 #include <string>
23 #include <vector>
24 #include <map>
25 
26 #include <drizzled/module/registry.h>
27 #include <drizzled/module/library.h>
28 #include <drizzled/module/graph.h>
29 #include <drizzled/module/vertex_handle.h>
30 
31 #include <drizzled/plugin.h>
32 #include <drizzled/show.h>
33 #include <drizzled/cursor.h>
34 #include <drizzled/abort_exception.h>
35 #include <drizzled/util/find_ptr.h>
36 
37 #include <boost/bind.hpp>
38 #include <boost/foreach.hpp>
39 
40 using namespace std;
41 
42 namespace drizzled {
43 
44 module::Registry::Registry() :
45  module_registry_(),
46  depend_graph_(new module::Graph()),
47  plugin_registry(),
48  deps_built_(false)
49 { }
50 
51 
52 module::Registry::~Registry()
53 {
54  /* Give all plugins a chance to cleanup, before
55  * all plugins are deleted.
56  * This can be used if shutdown code references
57  * other plugins.
58  */
59  BOOST_FOREACH(plugin::Plugin::map::reference it, plugin_registry)
60  it.second->shutdownPlugin();
61 
62  plugin::Plugin::vector error_plugins;
63  BOOST_FOREACH(plugin::Plugin::map::reference it, plugin_registry)
64  {
65  if (it.second->removeLast())
66  error_plugins.push_back(it.second);
67  else
68  delete it.second;
69  }
70 
71  BOOST_FOREACH(plugin::Plugin::vector::reference it, error_plugins)
72  delete it;
73 
74  plugin_registry.clear();
75 
76 #if 0
77  /*
78  @TODO When we delete modules here, we segfault on a bad string. Why?
79  */
80 
81  BOOST_FOREACH(ModuleMap::reference it, module_registry_)
82  delete it.second;
83  module_registry_.clear();
84 #endif
85  BOOST_FOREACH(LibraryMap::reference it, library_registry_)
86  delete it.second;
87  library_registry_.clear();
88 }
89 
90 void module::Registry::shutdown()
91 {
92  delete &singleton();
93 }
94 
95 module::Module* module::Registry::find(const std::string& name)
96 {
97  return find_ptr2(module_registry_, boost::to_lower_copy(name));
98 }
99 
100 void module::Registry::add(module::Module *handle)
101 {
102  std::string add_str(boost::to_lower_copy(handle->getName()));
103 
104  module_registry_[add_str]= handle;
105 
106  Vertex vertex_info(add_str, handle);
107  VertexDesc handle_vertex= boost::add_vertex(depend_graph_->getGraph());
108  depend_graph_->properties(handle_vertex)= vertex_info;
109 
110  handle->setVertexHandle(new VertexHandle(handle_vertex));
111 }
112 
113 void module::Registry::remove(module::Module *handle)
114 {
115  module_registry_.erase(boost::to_lower_copy(handle->getName()));
116 }
117 
118 void module::Registry::buildDeps()
119 {
120  BOOST_FOREACH(ModuleMap::reference map_iter, module_registry_)
121  {
122  Module* handle= map_iter.second;
123  BOOST_FOREACH(Module::Depends::const_reference handle_deps, handle->getDepends())
124  {
125  std::string dep_str(boost::to_lower_copy(handle_deps));
126  bool found_dep= false;
127  for (vertex_iter it= boost::vertices(depend_graph_->getGraph()).first; it != vertices(depend_graph_->getGraph()).second; it++)
128  {
129  if (depend_graph_->properties(*it).getName() == dep_str)
130  {
131  found_dep= true;
132  add_edge(handle->getVertexHandle()->getVertexDesc(), *it, depend_graph_->getGraph());
133  break;
134  }
135  }
136  if (not found_dep)
137  {
138  errmsg_printf(error::ERROR, _("Couldn't process plugin module dependencies. %s depends on %s but %s is not to be loaded.\n"),
139  handle->getName().c_str(), dep_str.c_str(), dep_str.c_str());
140  DRIZZLE_ABORT;
141  }
142  }
143  }
144  deps_built_= true;
145 }
146 
147 module::Registry::ModuleList module::Registry::getList()
148 {
149  if (not deps_built_)
150  buildDeps();
151  VertexList vertex_list;
152  boost::topological_sort(depend_graph_->getGraph(), std::back_inserter(vertex_list));
153  ModuleList plugins;
154  BOOST_FOREACH(VertexList::reference it, vertex_list)
155  {
156  if (Module* mod_ptr= depend_graph_->properties(it).getModule())
157  plugins.push_back(mod_ptr);
158  }
159  return plugins;
160 }
161 
162 module::Library *module::Registry::addLibrary(const std::string &plugin_name, bool builtin)
163 {
164  /* If this dll is already loaded just return it */
165  module::Library *library= findLibrary(plugin_name);
166  if (library)
167  return library;
168 
169  library= module::Library::loadLibrary(plugin_name, builtin);
170  if (library)
171  {
172  /* Add this dll to the map */
173  library_registry_.insert(make_pair(plugin_name, library));
174  }
175  return library;
176 }
177 
178 void module::Registry::removeLibrary(const std::string &plugin_name)
179 {
180  LibraryMap::iterator iter= library_registry_.find(plugin_name);
181  if (iter != library_registry_.end())
182  {
183  delete iter->second;
184  library_registry_.erase(iter);
185  }
186 }
187 
188 module::Library *module::Registry::findLibrary(const std::string &plugin_name) const
189 {
190  return find_ptr2(library_registry_, plugin_name);
191 }
192 
193 void module::Registry::shutdownModules()
194 {
195  module_shutdown(*this);
196 }
197 
198 } /* namespace drizzled */
TODO: Rename this file - func.h is stupid.
Definition: engine.cc:41