27 #include <boost/program_options.hpp>
29 #include <drizzled/option.h>
30 #include <drizzled/internal/m_string.h>
32 #include <drizzled/plugin.h>
33 #include <drizzled/module/load_list.h>
34 #include <drizzled/module/library.h>
35 #include <drizzled/module/registry.h>
37 #include <drizzled/sql_parse.h>
39 #include <drizzled/cursor.h>
40 #include <drizzled/set_var.h>
41 #include <drizzled/session.h>
42 #include <drizzled/item/null.h>
43 #include <drizzled/error.h>
44 #include <drizzled/gettext.h>
45 #include <drizzled/errmsg_print.h>
46 #include <drizzled/pthread_globals.h>
47 #include <drizzled/util/tokenize.h>
48 #include <drizzled/system_variables.h>
50 #include <boost/foreach.hpp>
57 namespace po=boost::program_options;
63 extern drizzled_builtin_list PANDORA_BUILTIN_SYMBOLS_LIST;
64 extern drizzled_builtin_list PANDORA_BUILTIN_LOAD_SYMBOLS_LIST;
67 PANDORA_BUILTIN_SYMBOLS_LIST, NULL
71 PANDORA_BUILTIN_LOAD_SYMBOLS_LIST, NULL
77 typedef vector<string> PluginOptions;
78 static PluginOptions opt_plugin_load;
79 static PluginOptions opt_plugin_add;
80 static PluginOptions opt_plugin_remove;
81 const char *builtin_plugins= PANDORA_BUILTIN_LIST;
82 const char *builtin_load_plugins= PANDORA_BUILTIN_LOAD_LIST;
88 static bool initialized=
false;
91 static bool reap_needed=
false;
97 static memory::Root plugin_mem_root(4096);
98 static uint32_t global_variables_dynamic_size= 0;
111 static void plugin_prune_list(vector<string> &plugin_list,
const vector<string> &plugins_to_remove);
114 const set<string> &plugin_list,
115 po::options_description &long_options,
116 bool builtin=
false);
135 po::options_description &long_options)
140 if (registry.find(library->getName()))
142 errmsg_printf(error::WARN, ER(ER_PLUGIN_EXISTS),
143 library->getName().c_str());
148 const module::Manifest *manifest= library->getManifest();
150 if (registry.find(manifest->name))
152 errmsg_printf(error::ERROR,
153 _(
"Plugin '%s' contains the name '%s' in its manifest, which "
154 "has already been registered.\n"),
155 library->getName().c_str(),
160 module::Module* tmp=
new module::Module(manifest, library);
162 if (!test_plugin_options(tmp_root, tmp, long_options))
167 errmsg_printf(error::ERROR, ER(ER_CANT_FIND_DL_ENTRY),
168 library->getName().c_str());
173 static void reap_plugins(module::Registry ®istry)
175 BOOST_FOREACH(module::Registry::ModuleMap::const_reference module, registry.getModulesMap())
176 delete module.second;
180 static bool plugin_initialize(module::Registry ®istry,
181 module::Module *module)
183 assert(module->isInited ==
false);
185 module::Context loading_context(registry, module);
186 if (module->getManifest().init)
188 if (module->getManifest().init(loading_context))
190 errmsg_printf(error::ERROR,
191 _(
"Plugin '%s' init function returned error.\n"),
192 module->getName().c_str());
196 module->isInited=
true;
200 static void compose_plugin_options(vector<string> &target,
201 vector<string> options)
203 BOOST_FOREACH(vector<string>::reference it, options)
204 tokenize(it, target, ",", true);
205 BOOST_FOREACH(vector<
string>::reference it, target)
206 std::replace(it.begin(), it.end(), '-', '_');
209 void compose_plugin_add(const vector<
string>& options)
211 compose_plugin_options(opt_plugin_add, options);
214 void compose_plugin_remove(
const vector<string>& options)
216 compose_plugin_options(opt_plugin_remove, options);
219 void notify_plugin_load(
const string& in_plugin_load)
221 tokenize(in_plugin_load, opt_plugin_load,
",",
true);
231 bool plugin_init(module::Registry ®istry,
232 po::options_description &long_options)
239 PluginOptions builtin_load_list;
240 tokenize(builtin_load_plugins, builtin_load_list,
",",
true);
242 PluginOptions builtin_list;
243 tokenize(builtin_plugins, builtin_list,
",",
true);
245 bool load_failed=
false;
247 if (opt_plugin_add.size() > 0)
249 for (PluginOptions::iterator iter= opt_plugin_add.begin();
250 iter != opt_plugin_add.end();
253 if (find(builtin_list.begin(),
254 builtin_list.end(), *iter) != builtin_list.end())
256 builtin_load_list.push_back(*iter);
260 opt_plugin_load.push_back(*iter);
265 if (opt_plugin_remove.size() > 0)
267 plugin_prune_list(opt_plugin_load, opt_plugin_remove);
268 plugin_prune_list(builtin_load_list, opt_plugin_remove);
271 memory::Root tmp_root(4096);
275 const set<string> builtin_list_set(builtin_load_list.begin(),
276 builtin_load_list.end());
277 load_failed= plugin_load_list(registry, &tmp_root,
278 builtin_list_set, long_options,
true);
286 const set<string> plugin_list_set(opt_plugin_load.begin(),
287 opt_plugin_load.end());
290 load_failed= plugin_load_list(registry, &tmp_root,
291 plugin_list_set, long_options);
303 bool plugin_finalize(module::Registry ®istry)
308 BOOST_FOREACH(module::Registry::ModuleList::const_reference module, registry.getList())
310 if (not module->isInited && plugin_initialize(registry, module))
312 registry.remove(module);
317 BOOST_FOREACH(plugin::Plugin::map::value_type value, registry.getPluginsMap())
319 value.second->prime();
327 void plugin_startup_window(module::Registry ®istry,
drizzled::Session &session)
329 BOOST_FOREACH(plugin::Plugin::map::value_type value, registry.getPluginsMap())
331 value.second->startup(session);
336 public unary_function<string, bool>
338 const string to_match;
344 result_type operator()(
const string &match_against)
346 return match_against == to_match;
350 static void plugin_prune_list(vector<string> &plugin_list,
351 const vector<string> &plugins_to_remove)
353 for (vector<string>::const_iterator iter= plugins_to_remove.begin();
354 iter != plugins_to_remove.end();
357 plugin_list.erase(remove_if(plugin_list.begin(),
367 static bool plugin_load_list(module::Registry ®istry,
368 memory::Root *tmp_root,
369 const set<string> &plugin_list,
370 po::options_description &long_options,
373 BOOST_FOREACH(
const string& plugin_name, plugin_list)
375 module::Library* library= registry.addLibrary(plugin_name, builtin);
378 errmsg_printf(error::ERROR,
379 _(
"Couldn't load plugin library named '%s'.\n"),
380 plugin_name.c_str());
384 tmp_root->free_root(MYF(memory::MARK_BLOCKS_FREE));
385 if (plugin_add(registry, tmp_root, library, long_options))
387 registry.removeLibrary(plugin_name);
388 errmsg_printf(error::ERROR,
389 _(
"Couldn't load plugin named '%s'.\n"),
390 plugin_name.c_str());
397 void module_shutdown(module::Registry ®istry)
403 reap_plugins(registry);
404 unlock_variables(NULL, &global_system_variables);
405 unlock_variables(NULL, &max_system_variables);
407 cleanup_variables(&global_system_variables);
408 cleanup_variables(&max_system_variables);
416 global_variables_dynamic_size= 0;
426 void plugin_sessionvar_init(Session *session)
428 session->variables.storage_engine= NULL;
429 cleanup_variables(&session->variables);
431 session->variables= global_system_variables;
432 session->variables.storage_engine= NULL;
435 session->variables.dynamic_variables_version= 0;
436 session->variables.dynamic_variables_size= 0;
437 session->variables.dynamic_variables_ptr= 0;
439 session->variables.storage_engine= global_system_variables.storage_engine;
446 static void unlock_variables(Session *,
struct drizzle_system_variables *vars)
448 vars->storage_engine= NULL;
458 static void cleanup_variables(drizzle_system_variables *vars)
460 assert(vars->storage_engine == NULL);
462 free(vars->dynamic_variables_ptr);
463 vars->dynamic_variables_ptr= NULL;
464 vars->dynamic_variables_size= 0;
465 vars->dynamic_variables_version= 0;
469 void plugin_sessionvar_cleanup(Session *session)
471 unlock_variables(session, &session->variables);
472 cleanup_variables(&session->variables);
488 static int test_plugin_options(memory::Root *,
489 module::Module *test_module,
490 po::options_description &long_options)
493 if (test_module->getManifest().init_options != NULL)
495 string plugin_section_title(
"Options used by ");
496 plugin_section_title.append(test_module->getName());
497 po::options_description module_options(plugin_section_title);
498 module::option_context opt_ctx(test_module->getName(),
499 module_options.add_options());
500 test_module->getManifest().init_options(opt_ctx);
501 long_options.add(module_options);
517 return my_charset_utf8_general_ci.strcasecmp(a.name, b.name);
525 vector<option> all_options;
531 std::map<std::string, module::Module *>::const_iterator modules=
532 registry.getModulesMap().begin();
534 while (modules != registry.getModulesMap().end())
541 if (p->getManifest().init_options != NULL)
547 for (;main_options->id; main_options++)
549 if (main_options->comment)
551 all_options.push_back(*main_options);
562 all_options.push_back(*main_options);
564 my_print_help(&*(all_options.begin()));
An Proxy Wrapper around options_description_easy_init.
void my_print_help_inc_plugins(option *main_options)
void free_root(myf MyFLAGS)
Deallocate everything used by alloc_root or just move used blocks to free list if called with MY_USED...