2
* Copyright (C) 2010 PrimeBase Technologies GmbH, Germany
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; version 2 of the License.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
* This plugin is an example events plugin that just prints some info for
26
* the events that it is tracking.
28
set global hello_events1_enable = ON;
29
set global hello_events1_watch_databases = "x";
30
set global hello_events1_watch_tables = "x,y";
37
#include <boost/program_options.hpp>
38
#include <drizzled/module/option_map.h>
39
#include "drizzled/session.h"
40
#include "hello_events.h"
41
namespace po= boost::program_options;
42
using namespace drizzled;
43
using namespace plugin;
46
#define PLUGIN_NAME "hello_events1"
48
static bool sysvar_hello_events_enabled= true;
49
static HelloEvents *hello_events= NULL;
50
static char *sysvar_table_list= NULL;
51
static char *sysvar_db_list= NULL;
54
* Event observer positions are used to set the order in which
55
* event observers are called in the case that more than one
56
* plugin is interested in the same event. You should only specify
57
* the order if it really matters because if more than one plugin
58
* request the same calling position only the first one gets it and
59
* the others will not be registered for the event. For this reason
60
* your plugin should always provide a way to reposition the event
61
* observer to resolve such conflicts.
63
* If position matters you will always initialy ask for the first position (1)
64
* or the last position (-1) in the calling order, for example it makes no sence
65
* to initially ask to be called in position 13.
67
static int32_t sysvar_before_write_position= 1; // Call this event observer first.
68
static int32_t sysvar_before_update_position= 1;
69
static int32_t sysvar_post_drop_db_position= -1; // I want my event observer to be called last. No reason, I just do!
72
//==================================
73
// My table event observers:
74
static bool observeBeforeInsertRecord(BeforeInsertRecordEventData &data)
79
data.session.setVariable("BEFORE_INSERT_RECORD", boost::lexical_cast<std::string>(count));
84
static void observeAfterInsertRecord(AfterInsertRecordEventData &data)
88
data.session.setVariable("AFTER_INSERT_RECORD", boost::lexical_cast<std::string>(count));
92
static bool observeBeforeDeleteRecord(BeforeDeleteRecordEventData &data)
96
data.session.setVariable("AFTER_DELETE_RECORD", boost::lexical_cast<std::string>(count));
101
static void observeAfterDeleteRecord(AfterDeleteRecordEventData &data)
105
data.session.setVariable("AFTER_DELETE_RECORD", boost::lexical_cast<std::string>(count));
109
static bool observeBeforeUpdateRecord(BeforeUpdateRecordEventData &data)
113
data.session.setVariable("BEFORE_UPDATE_RECORD", boost::lexical_cast<std::string>(count));
118
static void observeAfterUpdateRecord(AfterUpdateRecordEventData &data)
122
data.session.setVariable("AFTER_UPDATE_RECORD", boost::lexical_cast<std::string>(count));
125
//==================================
126
// My schema event observers:
127
static void observeAfterDropTable(AfterDropTableEventData &data)
131
data.session.setVariable("AFTER_DROP_TABLE", boost::lexical_cast<std::string>(count));
135
static void observeAfterRenameTable(AfterRenameTableEventData &data)
139
data.session.setVariable("AFTER_RENAME_TABLE", boost::lexical_cast<std::string>(count));
143
static void observeAfterCreateDatabase(AfterCreateDatabaseEventData &data)
147
data.session.setVariable("AFTER_CREATE_DATABASE", boost::lexical_cast<std::string>(count));
151
static void observeAfterDropDatabase(AfterDropDatabaseEventData &data)
155
data.session.setVariable("AFTER_DROP_DATABASE", boost::lexical_cast<std::string>(count));
159
static void observeConnectSession(ConnectSessionEventData &data)
163
data.session.setVariable("CONNECT_SESSION", boost::lexical_cast<std::string>(count));
167
static void observeDisconnectSession(DisconnectSessionEventData &data)
171
data.session.setVariable("DISCONNECT_SESSION", boost::lexical_cast<std::string>(count));
175
static void observeBeforeStatement(BeforeStatementEventData &data)
179
data.session.setVariable("BEFORE_STATEMENT", boost::lexical_cast<std::string>(count));
183
static void observeAfterStatement(AfterStatementEventData &data)
187
data.session.setVariable("AFTER_STATEMENT", boost::lexical_cast<std::string>(count));
190
HelloEvents::~HelloEvents()
192
/* These are strdup'd in option processing */
193
if (sysvar_table_list) {
194
free(sysvar_table_list);
195
sysvar_table_list = NULL;
198
if (sysvar_db_list) {
199
free(sysvar_db_list);
200
sysvar_db_list = NULL;
205
//==================================
206
/* This is where I register which table events my pluggin is interested in.*/
207
void HelloEvents::registerTableEventsDo(TableShare &table_share, EventObserverList &observers)
209
if ((is_enabled == false)
210
|| !isTableInteresting(table_share.getTableName())
211
|| !isDatabaseInteresting(table_share.getSchemaName()))
214
registerEvent(observers, BEFORE_INSERT_RECORD, sysvar_before_write_position); // I want to be called first if passible
215
registerEvent(observers, AFTER_INSERT_RECORD);
216
registerEvent(observers, BEFORE_UPDATE_RECORD, sysvar_before_update_position);
217
registerEvent(observers, AFTER_UPDATE_RECORD);
218
registerEvent(observers, BEFORE_DELETE_RECORD);
219
registerEvent(observers, AFTER_DELETE_RECORD);
222
//==================================
223
/* This is where I register which schema events my pluggin is interested in.*/
224
void HelloEvents::registerSchemaEventsDo(const std::string &db, EventObserverList &observers)
226
if ((is_enabled == false)
227
|| !isDatabaseInteresting(db))
230
registerEvent(observers, AFTER_DROP_TABLE);
231
registerEvent(observers, AFTER_RENAME_TABLE);
234
//==================================
235
/* This is where I register which session events my pluggin is interested in.*/
236
void HelloEvents::registerSessionEventsDo(Session &session, EventObserverList &observers)
238
if ((is_enabled == false)
239
|| !isSessionInteresting(session))
242
registerEvent(observers, AFTER_CREATE_DATABASE);
243
registerEvent(observers, AFTER_DROP_DATABASE, sysvar_post_drop_db_position);
244
registerEvent(observers, DISCONNECT_SESSION);
245
registerEvent(observers, CONNECT_SESSION);
246
registerEvent(observers, BEFORE_STATEMENT);
247
registerEvent(observers, AFTER_STATEMENT);
251
//==================================
252
/* The event observer.*/
253
bool HelloEvents::observeEventDo(EventData &data)
257
switch (data.event) {
258
case AFTER_DROP_TABLE:
259
observeAfterDropTable((AfterDropTableEventData &)data);
262
case AFTER_RENAME_TABLE:
263
observeAfterRenameTable((AfterRenameTableEventData &)data);
266
case BEFORE_INSERT_RECORD:
267
result = observeBeforeInsertRecord((BeforeInsertRecordEventData &)data);
270
case AFTER_INSERT_RECORD:
271
observeAfterInsertRecord((AfterInsertRecordEventData &)data);
274
case BEFORE_UPDATE_RECORD:
275
result = observeBeforeUpdateRecord((BeforeUpdateRecordEventData &)data);
278
case AFTER_UPDATE_RECORD:
279
observeAfterUpdateRecord((AfterUpdateRecordEventData &)data);
282
case BEFORE_DELETE_RECORD:
283
result = observeBeforeDeleteRecord((BeforeDeleteRecordEventData &)data);
286
case AFTER_DELETE_RECORD:
287
observeAfterDeleteRecord((AfterDeleteRecordEventData &)data);
290
case AFTER_CREATE_DATABASE:
291
observeAfterCreateDatabase((AfterCreateDatabaseEventData &)data);
294
case AFTER_DROP_DATABASE:
295
observeAfterDropDatabase((AfterDropDatabaseEventData &)data);
298
case CONNECT_SESSION:
299
observeConnectSession((ConnectSessionEventData &)data);
302
case DISCONNECT_SESSION:
303
observeDisconnectSession((DisconnectSessionEventData &)data);
306
case BEFORE_STATEMENT:
307
observeBeforeStatement((BeforeStatementEventData &)data);
310
case AFTER_STATEMENT:
311
observeAfterStatement((AfterStatementEventData &)data);
315
fprintf(stderr, "HelloEvents: Unexpected event '%s'\n", EventObserver::eventName(data.event));
322
//==================================
323
// Some custom things for my plugin:
326
/* Plugin initialization and system variables */
328
static void enable(Session *,
335
if (*(bool *)save != false)
337
hello_events->enable();
338
*(bool *) var_ptr= (bool) true;
342
hello_events->disable();
343
*(bool *) var_ptr= (bool) false;
349
static void set_db_list(Session *,
356
hello_events->setDatabasesOfInterest(*(const char **) save);
357
*(const char **) var_ptr= hello_events->getDatabasesOfInterest();
361
static void set_table_list(Session *,
368
hello_events->setTablesOfInterest(*(const char **) save);
369
*(const char **) var_ptr= hello_events->getTablesOfInterest();
374
static int init(module::Context &context)
376
const module::option_map &vm= context.getOptions();
377
if (vm.count("before-write-position"))
379
if (sysvar_before_write_position < 1 || sysvar_before_write_position > INT32_MAX -1)
381
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value of before-write-position\n"));
386
if (vm.count("before-update-position"))
388
if (sysvar_before_update_position < 1 || sysvar_before_update_position > INT32_MAX -1)
390
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value of before-update-position\n"));
395
if (vm.count("post-drop-db-position"))
397
if (sysvar_post_drop_db_position > -1 || sysvar_post_drop_db_position < INT32_MIN+1)
399
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value of before-update-position\n"));
404
if (vm.count("watch-databases"))
406
sysvar_db_list= strdup(vm["watch-databases"].as<string>().c_str());
411
sysvar_db_list= strdup("");
414
if (vm.count("watch-tables"))
416
sysvar_table_list= strdup(vm["watch-tables"].as<string>().c_str());
421
sysvar_table_list= strdup("");
423
hello_events= new HelloEvents(PLUGIN_NAME);
425
context.add(hello_events);
427
if (sysvar_hello_events_enabled)
429
hello_events->enable();
435
static void init_options(drizzled::module::option_context &context)
437
context("watch-databases",
439
N_("A comma delimited list of databases to watch"));
440
context("watch-tables",
442
N_("A comma delimited list of databases to watch"));
444
po::value<bool>(&sysvar_hello_events_enabled)->default_value(false)->zero_tokens(),
445
N_("Enable Example Events Plugin"));
446
context("before-write-position",
447
po::value<int32_t>(&sysvar_before_write_position)->default_value(1),
448
N_("Before write row event observer call position"));
449
context("before-update-position",
450
po::value<int32_t>(&sysvar_before_update_position)->default_value(1),
451
N_("Before update row event observer call position"));
452
context("post-drop-db-position",
453
po::value<int32_t>(&sysvar_post_drop_db_position)->default_value(-1),
454
N_("After drop database event observer call position"));
457
static DRIZZLE_SYSVAR_STR(watch_databases,
460
N_("A comma delimited list of databases to watch"),
461
NULL, /* check func */
462
set_db_list, /* update func */
465
static DRIZZLE_SYSVAR_STR(watch_tables,
468
N_("A comma delimited list of tables to watch"),
469
NULL, /* check func */
470
set_table_list, /* update func */
473
static DRIZZLE_SYSVAR_BOOL(enable,
474
sysvar_hello_events_enabled,
476
N_("Enable Example Events Plugin"),
477
NULL, /* check func */
478
enable, /* update func */
479
false /* default */);
481
static DRIZZLE_SYSVAR_INT(before_write_position,
482
sysvar_before_write_position,
484
N_("Before write row event observer call position"),
485
NULL, /* check func */
486
NULL, /* update func */
489
INT32_MAX -1, /* max */
492
static DRIZZLE_SYSVAR_INT(before_update_position,
493
sysvar_before_update_position,
495
N_("Before update row event observer call position"),
496
NULL, /* check func */
497
NULL, /* update func */
500
INT32_MAX -1, /* max */
503
static drizzle_sys_var* system_var[]= {
504
DRIZZLE_SYSVAR(watch_databases),
505
DRIZZLE_SYSVAR(watch_tables),
506
DRIZZLE_SYSVAR(enable),
507
DRIZZLE_SYSVAR(before_write_position),
508
DRIZZLE_SYSVAR(before_update_position),
512
DRIZZLE_DECLARE_PLUGIN
518
N_("An example events Plugin"),
520
init, /* Plugin Init */
521
system_var, /* system variables */
522
init_options /* config options */
524
DRIZZLE_DECLARE_PLUGIN_END;