Drizzled Public API Documentation

event_observer.h

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Definitions required for EventObserver plugin
00005  *
00006  *  Copyright (C) 2010 PrimeBase Technologies GmbH, Germany
00007  *
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; version 2 of the License.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  *
00021  * Barry Leslie
00022  *
00023  * 2010-05-12
00024  */
00025 
00026 /*
00027  * How to add a new event:
00028  *
00029  * In event_observer.h
00030  * 1: Add your event to EventType.
00031  * 2: Add it to EventObserver::eventName().
00032  * 3: Cerate a EventData class for it based on SessionEventData, SchemaEventData, 
00033  *  or TableEventData depending on the event type class.
00034  * 4: Add a static method to the EventObserver class, similar to beforeInsertRecord() for example,
00035  *  that will be called by drizzle.
00036  *
00037  * In event_observer.cc
00038  * 5: Impliment your static event method, similar to beforeInsertRecord() for example.
00039  * 6: Depending on the event type class add an event vector for it to the SessionEventObservers,
00040  *  SchemaEventObservers, or TableEventObservers class.
00041  *
00042  */
00043 #pragma once
00044 
00045 #include <drizzled/plugin/plugin.h>
00046 
00047 #include <string>
00048 
00049 #include <drizzled/visibility.h>
00050 
00051 namespace drizzled
00052 {
00053 
00054 class Table;
00055 class TableShare;
00056 class Session;
00057 
00058 namespace plugin
00059 {
00060 class EventObserverList;
00061 class EventData;
00062 class EventObserver;
00063 
00064 typedef std::vector<EventObserver *> EventObserverVector;
00065 typedef EventObserver* EventObserverPtr;
00066 
00067 class DRIZZLED_API EventObserver : public Plugin
00068 {
00069   EventObserver();
00070   EventObserver(const EventObserver &);
00071   EventObserver& operator=(const EventObserver &);
00072 public:
00073   explicit EventObserver(std::string name_arg)
00074     : Plugin(name_arg, "EventObserver")
00075   {}
00076   virtual ~EventObserver() {}
00077 
00078   enum EventType{
00079     /* Session events: */
00080     BEFORE_CREATE_DATABASE, AFTER_CREATE_DATABASE, 
00081     BEFORE_DROP_DATABASE,   AFTER_DROP_DATABASE,
00082     CONNECT_SESSION,
00083     DISCONNECT_SESSION,
00084     AFTER_STATEMENT,
00085     BEFORE_STATEMENT,
00086 
00087     /* Schema events: */
00088     BEFORE_DROP_TABLE,   AFTER_DROP_TABLE, 
00089     BEFORE_RENAME_TABLE, AFTER_RENAME_TABLE, 
00090 
00091     /* Table events: */
00092     BEFORE_INSERT_RECORD,   AFTER_INSERT_RECORD, 
00093     BEFORE_UPDATE_RECORD,   AFTER_UPDATE_RECORD, 
00094     BEFORE_DELETE_RECORD,   AFTER_DELETE_RECORD,
00095 
00096     /* The max event ID marker. */
00097     MAX_EVENT_COUNT
00098   };
00099 
00100   static const char *eventName(EventType event) 
00101   {
00102     switch(event) 
00103     {
00104     case BEFORE_DROP_TABLE:
00105       return "BEFORE_DROP_TABLE";
00106 
00107     case AFTER_DROP_TABLE:
00108       return "AFTER_DROP_TABLE";
00109 
00110     case BEFORE_RENAME_TABLE:
00111       return "BEFORE_RENAME_TABLE";
00112 
00113     case AFTER_RENAME_TABLE:
00114       return "AFTER_RENAME_TABLE";
00115 
00116     case BEFORE_INSERT_RECORD:
00117       return "BEFORE_INSERT_RECORD";
00118 
00119     case AFTER_INSERT_RECORD:
00120       return "AFTER_INSERT_RECORD";
00121 
00122     case BEFORE_UPDATE_RECORD:
00123       return "BEFORE_UPDATE_RECORD";
00124 
00125     case AFTER_UPDATE_RECORD:
00126       return "AFTER_UPDATE_RECORD";
00127 
00128     case BEFORE_DELETE_RECORD:
00129       return "BEFORE_DELETE_RECORD";
00130 
00131     case AFTER_DELETE_RECORD:
00132       return "AFTER_DELETE_RECORD";
00133 
00134     case BEFORE_CREATE_DATABASE:
00135       return "BEFORE_CREATE_DATABASE";
00136 
00137     case AFTER_CREATE_DATABASE:
00138       return "AFTER_CREATE_DATABASE";
00139 
00140     case BEFORE_DROP_DATABASE:
00141       return "BEFORE_DROP_DATABASE";
00142 
00143     case AFTER_DROP_DATABASE:
00144       return "AFTER_DROP_DATABASE";
00145 
00146     case CONNECT_SESSION:
00147       return "CONNECT_SESSION";
00148 
00149     case DISCONNECT_SESSION:
00150       return "DISCONNECT_SESSION";
00151 
00152     case AFTER_STATEMENT:
00153       return "AFTER_STATEMENT";
00154 
00155     case BEFORE_STATEMENT:
00156       return "BEFORE_STATEMENT";
00157 
00158     case MAX_EVENT_COUNT:
00159       break;
00160     }
00161 
00162     return "Unknown";
00163   }
00164 
00165   /*==========================================================*/
00166   /* registerEvents() must be implemented to allow the plugin to
00167    * register which events it is interested in.
00168  */
00169   virtual void registerTableEventsDo(TableShare &, EventObserverList &){}
00170   virtual void registerSchemaEventsDo(const std::string &/*db*/, EventObserverList &) {}
00171   virtual void registerSessionEventsDo(Session &, EventObserverList &) {}
00172 
00173   virtual bool observeEventDo(EventData &)= 0;
00174 
00175   /*==========================================================*/
00176   /* Static access methods called by drizzle: */
00177   static bool addPlugin(EventObserver *handler);
00178   static void removePlugin(EventObserver *handler);
00179 
00180   /*==========================================================*/
00181   /* Register an event of interest for this plugin. 
00182    * This is called from with in the plugin when registering itself.
00183    *
00184    * The position field is used to indicate the order the event observer is to be 
00185    * called. If the event observer must be called before any other observer then 
00186    * the position must be set to 1. If it must be called last then the position must be 
00187    * set to -1. A position of 0 indicated the position doesn't matter.
00188    *
00189    * If 2 plugins require the same position then which is called first in not guarenteed.
00190    * In this case a warrning will be logged but execution will continue.
00191    * 
00192    * It is good practice that if the event position matters not to hard code the position
00193    * but supply a systen variable so that it can be set at runtime so that the user can
00194    * decide which event should be called first.
00195  */
00196   void registerEvent(EventObserverList &observers, EventType event, int32_t position= 0); 
00197 
00198   /*==========================================================*/
00199   /* Called from drizzle to register all events for all event plugins 
00200    * interested in this table. 
00201  */
00202   static void registerTableEvents(TableShare &table_share); 
00203   static void deregisterTableEvents(TableShare &table_share); 
00204 
00205   /*==========================================================*/
00206   /* Called from drizzle to register all events for all event plugins 
00207    * interested in this database. 
00208  */
00209   static void registerSchemaEvents(Session &session, const std::string &db); 
00210   static void deregisterSchemaEvents(EventObserverList *observers); 
00211 
00212   /*==========================================================*/
00213   /* Called from drizzle to register all events for all event plugins 
00214    * interested in this session. 
00215  */
00216   static void registerSessionEvents(Session &session); 
00217   static void deregisterSessionEvents(EventObserverList *observers); 
00218 
00219 
00220   /*==========================================================*/
00221   /* Static meathods called by drizzle to notify interested plugins 
00222    * of a schema an event,
00223  */
00224   static bool beforeDropTable(Session &session, const drizzled::identifier::Table &table);
00225   static bool afterDropTable(Session &session, const drizzled::identifier::Table &table, int err);
00226   static bool beforeRenameTable(Session &session, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to);
00227   static bool afterRenameTable(Session &session, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to, int err);
00228   static bool connectSession(Session &session);
00229   static bool disconnectSession(Session &session);
00230   static bool beforeStatement(Session &session);
00231   static bool afterStatement(Session &session);
00232 
00233   /*==========================================================*/
00234   /* Static meathods called by drizzle to notify interested plugins 
00235    * of a table an event,
00236  */
00237   static bool beforeInsertRecord(Table &table, unsigned char *buf);
00238   static bool afterInsertRecord(Table &table, const unsigned char *buf, int err);
00239   static bool beforeDeleteRecord(Table &table, const unsigned char *buf);
00240   static bool afterDeleteRecord(Table &table, const unsigned char *buf, int err);
00241   static bool beforeUpdateRecord(Table &table, const unsigned char *old_data, unsigned char *new_data);
00242   static bool afterUpdateRecord(Table &table, const unsigned char *old_data, unsigned char *new_data, int err);
00243 
00244   /*==========================================================*/
00245   /* Static meathods called by drizzle to notify interested plugins 
00246    * of a table an event,
00247  */
00248   static bool beforeCreateDatabase(Session &session, const std::string &db);
00249   static bool afterCreateDatabase(Session &session, const std::string &db, int err);
00250   static bool beforeDropDatabase(Session &session, const std::string &db);
00251   static bool afterDropDatabase(Session &session, const std::string &db, int err);
00252 
00253   static const EventObserverVector &getEventObservers(void);
00254 
00255 };
00256 
00257 
00258 
00259 
00260 /* EventObserver data classes: */
00261 //======================================
00262 class EventData
00263 {
00264 public:
00265   EventObserver::EventType event;
00266 
00267   EventData(EventObserver::EventType event_arg): 
00268     event(event_arg),
00269     observerList(NULL)
00270   {}
00271   virtual ~EventData(){}
00272 
00273   // Call all the event observers that are registered for this event.
00274   virtual bool callEventObservers();
00275 
00276 protected:
00277   EventObserverList *observerList;
00278 
00279 };
00280 
00281 //-----
00282 class SessionEventData: public EventData
00283 {
00284 public:
00285   Session &session;
00286 
00287   SessionEventData(EventObserver::EventType event_arg, Session &session_arg): 
00288     EventData(event_arg),
00289     session(session_arg)
00290   {}
00291   virtual ~SessionEventData(){}
00292 
00293 
00294   // Call all the event observers that are registered for this event.
00295   virtual bool callEventObservers();
00296   
00297   static bool hasEvents(Session &in_session);
00298 };
00299 
00300 //-----
00301 class SchemaEventData: public EventData
00302 {
00303 public:
00304   Session &session;
00305   const std::string &db;
00306 
00307   SchemaEventData(EventObserver::EventType event_arg, Session &session_arg, const std::string &db_arg): 
00308     EventData(event_arg),
00309     session(session_arg),
00310     db(db_arg)
00311   {}
00312   virtual ~SchemaEventData(){}
00313 
00314 
00315   // Call all the event observers that are registered for this event.
00316   virtual bool callEventObservers();
00317   
00318 };
00319 
00320 //-----
00321 class TableEventData: public EventData
00322 {
00323 public:
00324   Session &session;
00325   Table &table;  
00326 
00327   TableEventData(EventObserver::EventType event_arg, Session &session_arg, Table &table_arg): 
00328     EventData(event_arg),
00329     session(session_arg),
00330     table(table_arg)
00331   {}
00332   virtual ~TableEventData(){}
00333 
00334 
00335   // Call all the event observers that are registered for this event.
00336   virtual bool callEventObservers();
00337   
00338   static bool hasEvents(Table &in_table);
00339 };
00340 
00341 //-----
00342 class BeforeCreateDatabaseEventData: public SessionEventData
00343 {
00344 public:
00345   const std::string &db;
00346 
00347   BeforeCreateDatabaseEventData(Session &session_arg, const std::string &db_arg): 
00348     SessionEventData(EventObserver::BEFORE_CREATE_DATABASE, session_arg), 
00349     db(db_arg)
00350   {}  
00351 };
00352 
00353 //-----
00354 class AfterCreateDatabaseEventData: public SessionEventData
00355 {
00356 public:
00357   const std::string &db;
00358   int err;
00359 
00360   AfterCreateDatabaseEventData(Session &session_arg, const std::string &db_arg, int err_arg): 
00361     SessionEventData(EventObserver::AFTER_CREATE_DATABASE, session_arg), 
00362     db(db_arg), 
00363     err(err_arg)
00364   {}  
00365 };
00366 
00367 //-----
00368 class BeforeDropDatabaseEventData: public SessionEventData
00369 {
00370 public:
00371   const std::string &db;
00372 
00373   BeforeDropDatabaseEventData(Session &session_arg, const std::string &db_arg): 
00374     SessionEventData(EventObserver::BEFORE_DROP_DATABASE, session_arg), 
00375     db(db_arg)
00376   {}  
00377 };
00378 
00379 //-----
00380 class AfterDropDatabaseEventData: public SessionEventData
00381 {
00382 public:
00383   const std::string &db;
00384   int err;
00385 
00386   AfterDropDatabaseEventData(Session &session_arg, const std::string &db_arg, int err_arg): 
00387     SessionEventData(EventObserver::AFTER_DROP_DATABASE, session_arg), 
00388     db(db_arg), 
00389     err(err_arg) 
00390   {}  
00391 };
00392 
00393 //-----
00394 class ConnectSessionEventData: public SessionEventData
00395 {
00396 public:
00397 
00398   ConnectSessionEventData(Session &session_arg):
00399     SessionEventData(EventObserver::CONNECT_SESSION, session_arg)
00400   {}  
00401 };
00402 
00403 //-----
00404 class DisconnectSessionEventData: public SessionEventData
00405 {
00406 public:
00407 
00408   DisconnectSessionEventData(Session &session_arg):
00409     SessionEventData(EventObserver::DISCONNECT_SESSION, session_arg)
00410   {}  
00411 };
00412 
00413 //-----
00414 class BeforeStatementEventData: public SessionEventData
00415 {
00416 public:
00417 
00418   BeforeStatementEventData(Session &session_arg):
00419     SessionEventData(EventObserver::BEFORE_STATEMENT, session_arg)
00420   {}  
00421 };
00422 
00423 //-----
00424 class AfterStatementEventData: public SessionEventData
00425 {
00426 public:
00427 
00428   AfterStatementEventData(Session &session_arg):
00429     SessionEventData(EventObserver::AFTER_STATEMENT, session_arg)
00430   {}  
00431 };
00432 
00433 //-----
00434 class BeforeDropTableEventData: public SchemaEventData
00435 {
00436 public:
00437   const drizzled::identifier::Table &table;
00438 
00439   BeforeDropTableEventData(Session &session_arg, const drizzled::identifier::Table &table_arg): 
00440     SchemaEventData(EventObserver::BEFORE_DROP_TABLE, session_arg, table_arg.getSchemaName()), 
00441     table(table_arg)
00442   {}  
00443 };
00444 
00445 //-----
00446 class AfterDropTableEventData: public SchemaEventData
00447 {
00448 public:
00449   const drizzled::identifier::Table &table;
00450   int err;
00451 
00452   AfterDropTableEventData(Session &session_arg, const drizzled::identifier::Table &table_arg, int err_arg): 
00453     SchemaEventData(EventObserver::AFTER_DROP_TABLE, session_arg, table_arg.getSchemaName()), 
00454     table(table_arg), 
00455     err(err_arg)
00456   {}  
00457 };
00458 
00459 //-----
00460 class BeforeRenameTableEventData: public SchemaEventData
00461 {
00462 public:
00463   const drizzled::identifier::Table &from;
00464   const drizzled::identifier::Table &to;
00465 
00466   BeforeRenameTableEventData(Session &session_arg, const drizzled::identifier::Table &from_arg, const drizzled::identifier::Table &to_arg): 
00467     SchemaEventData(EventObserver::BEFORE_RENAME_TABLE, session_arg, from_arg.getSchemaName()), 
00468     from(from_arg), 
00469     to(to_arg)
00470   {}  
00471 };
00472 
00473 //-----
00474 class AfterRenameTableEventData: public SchemaEventData
00475 {
00476 public:
00477   const drizzled::identifier::Table &from;
00478   const drizzled::identifier::Table &to;
00479   int err;
00480 
00481   AfterRenameTableEventData(Session &session_arg, const drizzled::identifier::Table &from_arg, const drizzled::identifier::Table &to_arg, int err_arg): 
00482     SchemaEventData(EventObserver::AFTER_RENAME_TABLE, session_arg, from_arg.getSchemaName()), 
00483     from(from_arg), 
00484     to(to_arg), 
00485     err(err_arg)
00486   {}  
00487 };
00488 
00489 //-----
00490 class BeforeInsertRecordEventData: public TableEventData
00491 {
00492 public:
00493   unsigned char *row;
00494 
00495   BeforeInsertRecordEventData(Session &session_arg, Table &table_arg, unsigned char *row_arg): 
00496     TableEventData(EventObserver::BEFORE_INSERT_RECORD, session_arg, table_arg), 
00497     row(row_arg)
00498   {}  
00499 };
00500 
00501 //-----
00502 class AfterInsertRecordEventData: public TableEventData
00503 {
00504 public:
00505   const unsigned char *row;
00506   int err;
00507 
00508   AfterInsertRecordEventData(Session &session_arg, Table &table_arg, const unsigned char *row_arg, int err_arg): 
00509     TableEventData(EventObserver::AFTER_INSERT_RECORD, session_arg, table_arg), 
00510     row(row_arg),
00511     err(err_arg)
00512   {}  
00513 };
00514 
00515 //-----
00516 class BeforeDeleteRecordEventData: public TableEventData
00517 {
00518 public:
00519   const unsigned char *row;
00520 
00521   BeforeDeleteRecordEventData(Session &session_arg, Table &table_arg, const unsigned char *row_arg): 
00522     TableEventData(EventObserver::BEFORE_DELETE_RECORD, session_arg, table_arg), 
00523     row(row_arg)
00524   {}  
00525 };
00526 
00527 //-----
00528 class AfterDeleteRecordEventData: public TableEventData
00529 {
00530 public:
00531   const unsigned char *row;
00532   int err;
00533 
00534   AfterDeleteRecordEventData(Session &session_arg, Table &table_arg, const unsigned char *row_arg, int err_arg): 
00535     TableEventData(EventObserver::AFTER_DELETE_RECORD, session_arg, table_arg), 
00536     row(row_arg),
00537     err(err_arg)
00538   {}  
00539 };
00540 
00541 //-----
00542 class BeforeUpdateRecordEventData: public TableEventData
00543 {
00544 public:
00545   const unsigned char *old_row;
00546   unsigned char *new_row;
00547 
00548   BeforeUpdateRecordEventData(Session &session_arg, Table &table_arg,  
00549                               const unsigned char *old_row_arg, 
00550                               unsigned char *new_row_arg): 
00551     TableEventData(EventObserver::BEFORE_UPDATE_RECORD, session_arg, table_arg), 
00552     old_row(old_row_arg),
00553     new_row(new_row_arg)      
00554   {}  
00555 };
00556 
00557 //-----
00558 class AfterUpdateRecordEventData: public TableEventData
00559 {
00560 public:
00561   const unsigned char *old_row;
00562   const unsigned char *new_row;
00563   int err;
00564 
00565   AfterUpdateRecordEventData(Session &session_arg, Table &table_arg, 
00566                              const unsigned char *old_row_arg, 
00567                              const unsigned char *new_row_arg, 
00568                              int err_arg): 
00569     TableEventData(EventObserver::AFTER_UPDATE_RECORD, session_arg, table_arg), 
00570     old_row(old_row_arg),
00571     new_row(new_row_arg),
00572     err(err_arg)
00573   {}  
00574 };
00575 
00576 //=======================================================
00577 
00578 } /* namespace plugin */
00579 } /* namespace drizzled */
00580