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