~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/event_observer.cc

Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB

Original revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu

Original Authors: Marko Mkel <marko.makela@oracle.com>
Original commit message:
Merge from mysql-5.1-innodb:

Post-merge fixes: Remove the MYSQL_VERSION_ID checks, because they only
apply to the InnoDB Plugin. Fix potential race condition accessing
trx->op_info and trx->detailed_error.
------------------------------------------------------------
revno: 3466
revision-id: marko.makela@oracle.com-20100514130815-ym7j7cfu88ro6km4
parent: marko.makela@oracle.com-20100514130228-n3n42nw7ht78k0wn
committer: Marko Mkel <marko.makela@oracle.com>
branch nick: mysql-5.1-innodb2
timestamp: Fri 2010-05-14 16:08:15 +0300
message:
  Make the InnoDB FOREIGN KEY parser understand multi-statements. (Bug #48024)
  Also make InnoDB thinks that /*/ only starts a comment. (Bug #53644).

  This fixes the bugs in the InnoDB Plugin.

  ha_innodb.h: Use trx_query_string() instead of trx_query() when
  available (MySQL 5.1.42 or later).

  innobase_get_stmt(): New function, to retrieve the currently running
  SQL statement.

  struct trx_struct: Remove mysql_query_str. Use innobase_get_stmt() instead.

  dict_strip_comments(): Add and observe the parameter sql_length. Treat
  /*/ as the start of a comment.

  dict_create_foreign_constraints(), row_table_add_foreign_constraints():
  Add the parameter sql_length.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2010 PrimeBase Technologies GmbH, Germany
 
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
 * Barry Leslie
 
20
 *
 
21
 * 2010-05-12
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include <string>
 
27
#include <vector>
 
28
 
 
29
#include "drizzled/session.h"
 
30
#include "drizzled/table_list.h"
 
31
#include "drizzled/definition/table.h"
 
32
#include "drizzled/module/registry.h"
 
33
#include "drizzled/plugin/event_observer.h"
 
34
#include <drizzled/util/functors.h>
 
35
#include <algorithm>
 
36
 
 
37
 
 
38
 
 
39
using namespace std;
 
40
 
 
41
namespace drizzled
 
42
{
 
43
 
 
44
namespace plugin
 
45
{
 
46
 
 
47
/*============================*/
 
48
  // Basic plugin registration stuff.
 
49
  EventObserverVector all_event_plugins;
 
50
 
 
51
  const EventObserverVector &EventObserver::getEventObservers(void)
 
52
  {
 
53
    return all_event_plugins;
 
54
  }
 
55
 
 
56
  //---------
 
57
  bool EventObserver::addPlugin(EventObserver *handler)
 
58
  {
 
59
    if (handler != NULL)
 
60
      all_event_plugins.push_back(handler);
 
61
    return false;
 
62
  }
 
63
 
 
64
  //---------
 
65
  void EventObserver::removePlugin(EventObserver *handler)
 
66
  {
 
67
    if (handler != NULL)
 
68
      all_event_plugins.erase(find(all_event_plugins.begin(), all_event_plugins.end(), handler));
 
69
  }
 
70
 
 
71
 
 
72
  /* 
 
73
   * The Event Observer list class in which plugins register which events they
 
74
   * are interested in.
 
75
   *
 
76
   * Each table share for example, will have one of these hung on it to store
 
77
   * a list off all event observers interested in it and which events they are
 
78
   * interested in.
 
79
 */
 
80
  class EventObserverList
 
81
  {
 
82
 
 
83
  public:
 
84
    typedef multimap<uint32_t, EventObserver *> ObserverMap;
 
85
 
 
86
  private:
 
87
    /* A list of lists indexed by event type. */
 
88
    vector<ObserverMap *> event_observer_lists;
 
89
 
 
90
  public:
 
91
 
 
92
    EventObserverList()
 
93
    {
 
94
                        // Initialize the list with NULL pointers.
 
95
                        event_observer_lists.assign(EventObserver::MAX_EVENT_COUNT, NULL);
 
96
    }
 
97
 
 
98
    ~EventObserverList()
 
99
    {
 
100
      for_each(event_observer_lists.begin(),
 
101
               event_observer_lists.end(),
 
102
               SafeDeletePtr());
 
103
                        event_observer_lists.clear();
 
104
    }
 
105
 
 
106
    /* Add the observer to the observer list for the even, positioning it if required.
 
107
     *
 
108
     * Note: Event observers are storted in a multimap object so that the order in which
 
109
     * they are called can be sorted based on the requested position. Lookups are never done
 
110
     * on the multimap, once filled it is used as a vector.
 
111
   */
 
112
    void addObserver(EventObserver *eventObserver, enum EventObserver::EventType event, int32_t position)
 
113
    {
 
114
      uint32_t event_pos;
 
115
      ObserverMap *observers;
 
116
 
 
117
      observers= event_observer_lists[event];
 
118
      if (observers == NULL) 
 
119
      {
 
120
        observers= new ObserverMap();
 
121
        event_observer_lists[event]= observers;
 
122
      }
 
123
 
 
124
      if (position == 0)
 
125
        event_pos= INT32_MAX; // Set the event position to be in the middle.
 
126
      else
 
127
        event_pos= (uint32_t) position;
 
128
 
 
129
      /* If positioned then check if the position is already taken. */
 
130
      if (position) 
 
131
      {
 
132
        if (observers->find(event_pos) != observers->end())
 
133
        {
 
134
          errmsg_printf(ERRMSG_LVL_WARN,
 
135
                        _("EventObserverList::addEventObserver() Duplicate event position %d for event '%s' from EventObserver plugin '%s'"),
 
136
                        position,
 
137
                        EventObserver::eventName(event), 
 
138
                        eventObserver->getName().c_str());
 
139
        }
 
140
      }
 
141
 
 
142
      observers->insert(pair<uint32_t, EventObserver *>(event_pos, eventObserver) );
 
143
    }
 
144
 
 
145
 
 
146
    /* Get the observer list for an event type. Will return NULL if no observer exists.*/
 
147
    ObserverMap *getObservers(enum EventObserver::EventType event)
 
148
    {
 
149
      return event_observer_lists[event];
 
150
    }
 
151
  };
 
152
 
 
153
 
 
154
  //---------
 
155
  /* registerEvent() is called from the event observer plugins to add themselves to
 
156
   * the event observer list to be notified when the specified event takes place.
 
157
   */ 
 
158
  void EventObserver::registerEvent(EventObserverList &observers, EventType event, int32_t position)
 
159
  {
 
160
    observers.addObserver(this, event, position);
 
161
  }
 
162
 
 
163
  /*========================================================*/
 
164
  /*              Table Event Observer handling:           */
 
165
  /*========================================================*/
 
166
 
 
167
  //----------
 
168
  /* For each EventObserver plugin call its registerTableEventsDo() meathod so that it can
 
169
   * register what events, if any, it is interested in on this table.
 
170
   */ 
 
171
  class RegisterTableEventsIterate : public unary_function<EventObserver *, void>
 
172
  {
 
173
    TableShare &table_share;
 
174
    EventObserverList &observers;
 
175
 
 
176
  public:
 
177
    RegisterTableEventsIterate(TableShare &table_share_arg, EventObserverList &observers_arg): 
 
178
      table_share(table_share_arg), observers(observers_arg) {}
 
179
    inline result_type operator() (argument_type eventObserver)
 
180
    {
 
181
      eventObserver->registerTableEventsDo(table_share, observers);
 
182
    }
 
183
  };
 
184
 
 
185
  //----------
 
186
  /* 
 
187
   * registerTableEvents() is called by drizzle to register all plugins that
 
188
   * may be interested in table events on the newly created TableShare object.
 
189
   */ 
 
190
  void EventObserver::registerTableEvents(TableShare &table_share)
 
191
  {
 
192
    if (all_event_plugins.empty())
 
193
      return;
 
194
 
 
195
    EventObserverList *observers;
 
196
 
 
197
    observers= table_share.getTableObservers();
 
198
 
 
199
    if (observers != NULL) 
 
200
                {
 
201
                        errmsg_printf(ERRMSG_LVL_WARN,
 
202
                                                                        _("EventObserver::registerTableEvents(): Table already has events registered on it: probable programming error."));
 
203
                        table_share.setTableObservers(NULL);
 
204
      delete observers;
 
205
    }
 
206
 
 
207
                observers= new EventObserverList();
 
208
                table_share.setTableObservers(observers);
 
209
 
 
210
 
 
211
    for_each(all_event_plugins.begin(), all_event_plugins.end(),
 
212
             RegisterTableEventsIterate(table_share, *observers));
 
213
 
 
214
  }
 
215
 
 
216
  //----------
 
217
  /* Cleanup before freeing the TableShare object. */
 
218
  void EventObserver::deregisterTableEvents(TableShare &table_share)
 
219
  {
 
220
   if (all_event_plugins.empty())
 
221
      return;
 
222
 
 
223
    EventObserverList *observers;
 
224
 
 
225
    observers= table_share.getTableObservers();
 
226
 
 
227
    if (observers) 
 
228
    {
 
229
      table_share.setTableObservers(NULL);
 
230
      delete observers;
 
231
    }
 
232
  }
 
233
 
 
234
 
 
235
  /*========================================================*/
 
236
  /*              Schema Event Observer handling:           */
 
237
  /*========================================================*/
 
238
 
 
239
  //----------
 
240
  /* For each EventObserver plugin call its registerSchemaEventsDo() meathod so that it can
 
241
   * register what events, if any, it is interested in on the schema.
 
242
   */ 
 
243
  class RegisterSchemaEventsIterate : public unary_function<EventObserver *, void>
 
244
  {
 
245
    const std::string &db;
 
246
    EventObserverList &observers;
 
247
  public:
 
248
    RegisterSchemaEventsIterate(const std::string &db_arg, EventObserverList &observers_arg) :     
 
249
      db(db_arg),
 
250
      observers(observers_arg){}
 
251
 
 
252
    inline result_type operator() (argument_type eventObserver)
 
253
    {
 
254
      eventObserver->registerSchemaEventsDo(db, observers);
 
255
    }
 
256
  };
 
257
 
 
258
  //----------
 
259
  /* 
 
260
   * registerSchemaEvents() is called by drizzle to register all plugins that
 
261
   * may be interested in schema events on the database.
 
262
   */ 
 
263
  void EventObserver::registerSchemaEvents(Session &session, const std::string &db)
 
264
  {
 
265
    if (all_event_plugins.empty())
 
266
      return;
 
267
 
 
268
    EventObserverList *observers;
 
269
 
 
270
    observers= session.getSchemaObservers(db);
 
271
 
 
272
    if (observers == NULL) 
 
273
    {
 
274
      observers= new EventObserverList();
 
275
      session.setSchemaObservers(db, observers);
 
276
   }
 
277
 
 
278
    for_each(all_event_plugins.begin(), all_event_plugins.end(),
 
279
             RegisterSchemaEventsIterate(db, *observers));
 
280
 
 
281
  }
 
282
 
 
283
  //----------
 
284
  /* Cleanup before freeing the Session object. */
 
285
  void EventObserver::deregisterSchemaEvents(Session &session, const std::string &db)
 
286
  {
 
287
    if (all_event_plugins.empty())
 
288
      return;
 
289
 
 
290
    EventObserverList *observers;
 
291
 
 
292
    observers= session.getSchemaObservers(db);
 
293
 
 
294
    if (observers) 
 
295
    {
 
296
      session.setSchemaObservers(db, NULL);
 
297
      delete observers;
 
298
    }
 
299
  }
 
300
 
 
301
  /*========================================================*/
 
302
  /*             Session Event Observer handling:           */
 
303
  /*========================================================*/
 
304
 
 
305
  //----------
 
306
  /* For each EventObserver plugin call its registerSessionEventsDo() meathod so that it can
 
307
   * register what events, if any, it is interested in on this session.
 
308
   */ 
 
309
  class RegisterSessionEventsIterate : public unary_function<EventObserver *, void>
 
310
  {
 
311
    Session &session;
 
312
    EventObserverList &observers;
 
313
  public:
 
314
    RegisterSessionEventsIterate(Session &session_arg, EventObserverList &observers_arg) : 
 
315
      session(session_arg), observers(observers_arg) {}
 
316
    inline result_type operator() (argument_type eventObserver)
 
317
    {
 
318
      eventObserver->registerSessionEventsDo(session, observers);
 
319
    }
 
320
  };
 
321
 
 
322
  //----------
 
323
  /* 
 
324
   * registerSessionEvents() is called by drizzle to register all plugins that
 
325
   * may be interested in session events on the newly created session.
 
326
   */ 
 
327
  void EventObserver::registerSessionEvents(Session &session)
 
328
  {
 
329
    if (all_event_plugins.empty())
 
330
      return;
 
331
 
 
332
    EventObserverList *observers;
 
333
 
 
334
    observers= session.getSessionObservers();
 
335
                if (observers) { // This should not happed
 
336
                        errmsg_printf(ERRMSG_LVL_WARN,
 
337
                                                                        _("EventObserver::registerSessionEvents(): Session already has events registered on it: probable programming error."));
 
338
                        session.setSessionObservers(NULL);
 
339
                        delete observers;
 
340
                }
 
341
 
 
342
        observers= new EventObserverList();
 
343
        session.setSessionObservers(observers);
 
344
 
 
345
    for_each(all_event_plugins.begin(), all_event_plugins.end(),
 
346
             RegisterSessionEventsIterate(session, *observers));
 
347
 
 
348
  }
 
349
 
 
350
  //----------
 
351
  /* Cleanup before freeing the session object. */
 
352
  void EventObserver::deregisterSessionEvents(Session &session)
 
353
  {
 
354
    if (all_event_plugins.empty())
 
355
      return;
 
356
 
 
357
    EventObserverList *observers;
 
358
 
 
359
    observers= session.getSessionObservers();
 
360
 
 
361
    if (observers) 
 
362
    {
 
363
      session.setSessionObservers(NULL);
 
364
      delete observers;
 
365
    }
 
366
  }
 
367
 
 
368
 
 
369
  /* Event observer list iterator: */
 
370
  //----------
 
371
  class EventIterate : public unary_function<pair<uint32_t, EventObserver *>, bool>
 
372
  {
 
373
    EventData &data;
 
374
 
 
375
  public:
 
376
    EventIterate(EventData &data_arg) :
 
377
      unary_function<pair<uint32_t, EventObserver *>, bool>(),
 
378
      data(data_arg)
 
379
    {}
 
380
 
 
381
    inline result_type operator()(argument_type handler)
 
382
    {
 
383
      bool result= handler.second->observeEventDo(data);
 
384
      if (result)
 
385
      {
 
386
        /* TRANSLATORS: The leading word "EventObserver" is the name
 
387
          of the plugin api, and so should not be translated. */
 
388
        errmsg_printf(ERRMSG_LVL_ERROR,
 
389
                      _("EventIterate event handler '%s' failed for event '%s'"),
 
390
                      handler.second->getName().c_str(), handler.second->eventName(data.event));
 
391
 
 
392
      }
 
393
      return result;
 
394
    }
 
395
  };
 
396
 
 
397
 
 
398
  /*==========================================================*/
 
399
  /* Generic meathods called by drizzle to notify all interested  
 
400
   * plugins of an event,
 
401
 */
 
402
 
 
403
  // Call all event observers interested in the event.
 
404
  bool EventData::callEventObservers()
 
405
  {
 
406
    EventObserverList::ObserverMap *eventObservers;
 
407
 
 
408
    if (observerList == NULL)
 
409
      return false; // Nobody was interested in the event. :(
 
410
 
 
411
    eventObservers = observerList->getObservers(event);
 
412
 
 
413
    if (eventObservers == NULL)
 
414
      return false; // Nobody was interested in the event. :(
 
415
 
 
416
    /* Use find_if instead of foreach so that we can collect return codes */
 
417
    EventObserverList::ObserverMap::iterator iter=
 
418
      find_if(eventObservers->begin(), eventObservers->end(),
 
419
              EventIterate(*this)); 
 
420
    /* If iter is == end() here, that means that all of the plugins returned
 
421
     * false, which in this case means they all succeeded. Since we want to 
 
422
     * return false on success, we return the value of the two being !=.
 
423
   */
 
424
    return iter != eventObservers->end();
 
425
  }
 
426
 
 
427
  //--------
 
428
  bool SessionEventData::callEventObservers()
 
429
  {
 
430
    observerList= session.getSessionObservers();
 
431
 
 
432
    return EventData::callEventObservers();
 
433
  }
 
434
 
 
435
  //--------
 
436
  bool SchemaEventData::callEventObservers()
 
437
  {
 
438
    observerList= session.getSchemaObservers(db);
 
439
    if (!observerList) 
 
440
    {
 
441
      EventObserver::registerSchemaEvents(session, db);
 
442
      observerList= session.getSchemaObservers(db);
 
443
    }
 
444
 
 
445
    return EventData::callEventObservers();
 
446
  }
 
447
 
 
448
  //--------
 
449
  bool TableEventData::callEventObservers()
 
450
  {
 
451
    observerList= table.getMutableShare()->getTableObservers();
 
452
 
 
453
    return EventData::callEventObservers();
 
454
  }
 
455
 
 
456
  /*==========================================================*/
 
457
  /* Static meathods called by drizzle to notify interested plugins 
 
458
   * of a schema event.
 
459
 */
 
460
  bool EventObserver::beforeDropTable(Session &session, const drizzled::TableIdentifier &table)
 
461
  {
 
462
    if (all_event_plugins.empty())
 
463
      return false;
 
464
 
 
465
    BeforeDropTableEventData eventData(session, table);
 
466
    return eventData.callEventObservers();
 
467
  }
 
468
 
 
469
  bool EventObserver::afterDropTable(Session &session, const drizzled::TableIdentifier &table, int err)
 
470
  {
 
471
    if (all_event_plugins.empty())
 
472
      return false;
 
473
 
 
474
    AfterDropTableEventData eventData(session, table, err);
 
475
    return eventData.callEventObservers();
 
476
  }
 
477
 
 
478
  bool EventObserver::beforeRenameTable(Session &session, const drizzled::TableIdentifier &from, const drizzled::TableIdentifier &to)
 
479
  {
 
480
    if (all_event_plugins.empty())
 
481
      return false;
 
482
 
 
483
    BeforeRenameTableEventData eventData(session, from, to);
 
484
    return eventData.callEventObservers();
 
485
  }
 
486
 
 
487
  bool EventObserver::afterRenameTable(Session &session, const drizzled::TableIdentifier &from, const drizzled::TableIdentifier &to, int err)
 
488
  {
 
489
    if (all_event_plugins.empty())
 
490
      return false;
 
491
 
 
492
    AfterRenameTableEventData eventData(session, from, to, err);
 
493
    return eventData.callEventObservers();
 
494
  }
 
495
 
 
496
  /*==========================================================*/
 
497
  /* Static meathods called by drizzle to notify interested plugins 
 
498
   * of a table event.
 
499
   *
 
500
   * A quick test is done first to see if there are any interested observers.
 
501
 */
 
502
  bool EventObserver::beforeInsertRecord(Table &table, unsigned char *buf)
 
503
  {
 
504
    if (all_event_plugins.empty() || !TableEventData::hasEvents(table))
 
505
      return false;
 
506
 
 
507
    BeforeInsertRecordEventData eventData(*(table.in_use), table, buf);
 
508
    return eventData.callEventObservers();
 
509
  }
 
510
 
 
511
  bool EventObserver::afterInsertRecord(Table &table, const unsigned char *buf, int err)
 
512
  {
 
513
    if (all_event_plugins.empty() || !TableEventData::hasEvents(table))
 
514
      return false;
 
515
 
 
516
    AfterInsertRecordEventData eventData(*(table.in_use), table, buf, err);
 
517
    return eventData.callEventObservers();
 
518
  }
 
519
 
 
520
  bool EventObserver::beforeDeleteRecord(Table &table, const unsigned char *buf)
 
521
  {
 
522
    if (all_event_plugins.empty() || !TableEventData::hasEvents(table))
 
523
      return false;
 
524
 
 
525
    BeforeDeleteRecordEventData eventData(*(table.in_use), table, buf);
 
526
    return eventData.callEventObservers();
 
527
  }
 
528
 
 
529
  bool EventObserver::afterDeleteRecord(Table &table, const unsigned char *buf, int err)
 
530
  {
 
531
    if (all_event_plugins.empty() || !TableEventData::hasEvents(table))
 
532
      return false;
 
533
 
 
534
    AfterDeleteRecordEventData eventData(*(table.in_use), table, buf, err);
 
535
    return eventData.callEventObservers();
 
536
  }
 
537
 
 
538
  bool EventObserver::beforeUpdateRecord(Table &table, const unsigned char *old_data, unsigned char *new_data)
 
539
  {
 
540
    if (all_event_plugins.empty() || !TableEventData::hasEvents(table))
 
541
      return false;
 
542
 
 
543
    BeforeUpdateRecordEventData eventData(*(table.in_use), table, old_data, new_data);
 
544
    return eventData.callEventObservers();
 
545
  }
 
546
 
 
547
  bool EventObserver::afterUpdateRecord(Table &table, const unsigned char *old_data, unsigned char *new_data, int err)
 
548
  {
 
549
    if (all_event_plugins.empty() || !TableEventData::hasEvents(table))
 
550
      return false;
 
551
 
 
552
    AfterUpdateRecordEventData eventData(*(table.in_use), table, old_data, new_data, err);
 
553
    return eventData.callEventObservers();
 
554
  }
 
555
 
 
556
  /*==========================================================*/
 
557
  /* Static meathods called by drizzle to notify interested plugins 
 
558
   * of a session event.
 
559
   *
 
560
   * A quick test is done first to see if there are any interested observers.
 
561
*/
 
562
  bool EventObserver::beforeCreateDatabase(Session &session, const std::string &db)
 
563
  {
 
564
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
565
      return false;
 
566
 
 
567
    BeforeCreateDatabaseEventData eventData(session, db);
 
568
    return eventData.callEventObservers();
 
569
  }
 
570
 
 
571
  bool EventObserver::afterCreateDatabase(Session &session, const std::string &db, int err)
 
572
  {
 
573
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
574
      return false;
 
575
 
 
576
    AfterCreateDatabaseEventData eventData(session, db, err);
 
577
    return eventData.callEventObservers();
 
578
  }
 
579
 
 
580
  bool EventObserver::beforeDropDatabase(Session &session, const std::string &db)
 
581
  {
 
582
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
583
      return false;
 
584
 
 
585
    BeforeDropDatabaseEventData eventData(session, db);
 
586
    return eventData.callEventObservers();
 
587
  }
 
588
 
 
589
  bool EventObserver::afterDropDatabase(Session &session, const std::string &db, int err)
 
590
  {
 
591
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
592
      return false;
 
593
 
 
594
    AfterDropDatabaseEventData eventData(session, db, err);
 
595
    return eventData.callEventObservers();
 
596
  }
 
597
 
 
598
  bool EventObserver::connectSession(Session &session)
 
599
  {
 
600
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
601
      return false;
 
602
 
 
603
    ConnectSessionEventData eventData(session);
 
604
    return eventData.callEventObservers();
 
605
  }
 
606
 
 
607
  bool EventObserver::disconnectSession(Session &session)
 
608
  {
 
609
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
610
      return false;
 
611
 
 
612
    DisconnectSessionEventData eventData(session);
 
613
    return eventData.callEventObservers();
 
614
  }
 
615
 
 
616
  bool EventObserver::beforeStatement(Session &session)
 
617
  {
 
618
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
619
      return false;
 
620
 
 
621
    BeforeStatementEventData eventData(session);
 
622
    return eventData.callEventObservers();
 
623
  }
 
624
 
 
625
  bool EventObserver::afterStatement(Session &session)
 
626
  {
 
627
    if (all_event_plugins.empty() || !SessionEventData::hasEvents(session))
 
628
      return false;
 
629
 
 
630
    AfterStatementEventData eventData(session);
 
631
    return eventData.callEventObservers();
 
632
  }
 
633
 
 
634
 
 
635
} /* namespace plugin */
 
636
} /* namespace drizzled */