1
/* Copyright (c) 2003-2007 MySQL AB, 2010 Sun Microsystems, Inc.
2
Use is subject to license terms
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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
17
#ifndef NdbEventOperation_H
18
#define NdbEventOperation_H
20
class NdbGlobalEventBuffer;
21
class NdbEventOperationImpl;
24
* @class NdbEventOperation
25
* @brief Class of operations for getting change events from database.
27
* Brief description on how to work with events:
29
* - An event, represented by an NdbDictionary::Event, i created in the
31
* NdbDictionary::Dictionary::createEvent() (note that this can be done
32
* by any application or thread and not necessarily by the "listener")
33
* - To listen to events, an NdbEventOperation object is instantiated by
34
* Ndb::createEventOperation()
35
* - execute() starts the event flow. Use Ndb::pollEvents() to wait
36
* for an event to occur. Use Ndb::nextEvent() to iterate
37
* through the events that have occured.
38
* - The instance is removed by Ndb::dropEventOperation()
41
* @ref ndbapi_event.cpp
45
* - Maximum number of active NdbEventOperations are now set at compile time.
46
* Today 100. This will become a configuration parameter later.
47
* - Maximum number of NdbEventOperations tied to same event are maximum 16
52
* - When several NdbEventOperation's are tied to the same event in the same
53
* process they will share the circular buffer. The BufferLength will then
54
* be the same for all and decided by the first NdbEventOperation
55
* instantiation. Just make sure to instantiate the "largest" one first.
56
* - Today all events INSERT/DELETE/UPDATE and all changed attributes are
57
* sent to the API, even if only specific attributes have been specified.
58
* These are however hidden from the user and only relevant data is shown
59
* after Ndb::nextEvent().
60
* - "False" exits from Ndb::pollEvents() may occur and thus
61
* the subsequent Ndb::nextEvent() will return NULL,
62
* since there was no available data. Just do Ndb::pollEvents() again.
63
* - Event code does not check table schema version. Make sure to drop events
64
* after table is dropped. Will be fixed in later
66
* - If a node failure has occured not all events will be recieved
67
* anymore. Drop NdbEventOperation and Create again after nodes are up
68
* again. Will be fixed in later versions.
72
* - Tests have been run on 1-node and 2-node systems
74
* Useful API programs:
76
* - ndb_select_all -d sys 'NDB$EVENTS_0'
77
* shows contents in the system table containing created events.
79
* @note this is an inteface to viewing events that is subject to change
81
class NdbEventOperation {
84
* State of the NdbEventOperation object
87
EO_CREATED, ///< Created but execute() not called
88
EO_EXECUTING, ///< execute() called
89
EO_DROPPED, ///< Waiting to be deleted, Object unusable.
90
EO_ERROR ///< An error has occurred. Object unusable.
93
* Retrieve current state of the NdbEventOperation object
97
* See NdbDictionary::Event. Default is false.
99
void mergeEvents(bool flag);
102
* Activates the NdbEventOperation to start receiving events. The
103
* changed attribute values may be retrieved after Ndb::nextEvent()
104
* has returned not NULL. The getValue() methods must be called
105
* prior to execute().
107
* @return 0 if successful otherwise -1.
112
* Defines a retrieval operation of an attribute value.
113
* The NDB API allocate memory for the NdbRecAttr object that
114
* will hold the returned attribute value.
116
* @note Note that it is the applications responsibility
117
* to allocate enough memory for aValue (if non-NULL).
118
* The buffer aValue supplied by the application must be
119
* aligned appropriately. The buffer is used directly
120
* (avoiding a copy penalty) only if it is aligned on a
121
* 4-byte boundary and the attribute size in bytes
122
* (i.e. NdbRecAttr::attrSize() times NdbRecAttr::arraySize() is
125
* @note There are two versions, getValue() and
126
* getPreValue() for retrieving the current and
127
* previous value repectively.
129
* @note This method does not fetch the attribute value from
130
* the database! The NdbRecAttr object returned by this method
131
* is <em>not</em> readable/printable before the
132
* execute() has been made and
133
* Ndb::nextEvent() has returned not NULL.
134
* If a specific attribute has not changed the corresponding
135
* NdbRecAttr will be in state UNDEFINED. This is checked by
136
* NdbRecAttr::isNULL() which then returns -1.
138
* @param anAttrName Attribute name
139
* @param aValue If this is non-NULL, then the attribute value
140
* will be returned in this parameter.<br>
141
* If NULL, then the attribute value will only
142
* be stored in the returned NdbRecAttr object.
143
* @return An NdbRecAttr object to hold the value of
144
* the attribute, or a NULL pointer
145
* (indicating error).
147
NdbRecAttr *getValue(const char *anAttrName, char *aValue = 0);
151
NdbRecAttr *getPreValue(const char *anAttrName, char *aValue = 0);
154
* These methods replace getValue/getPreValue for blobs. Each
155
* method creates a blob handle NdbBlob. The handle supports only
156
* read operations. See NdbBlob.
158
NdbBlob* getBlobHandle(const char *anAttrName);
159
NdbBlob* getPreBlobHandle(const char *anAttrName);
161
int isOverrun() const;
164
* In the current implementation a nodefailiure may cause loss of events,
165
* in which case isConsistent() will return false
167
bool isConsistent() const;
170
* Query for occured event type.
172
* @note Only valid after Ndb::nextEvent() has been called and
173
* returned a not NULL value
175
* @return type of event
177
NdbDictionary::Event::TableEvent getEventType() const;
180
* Check if table name has changed, for event TE_ALTER
182
bool tableNameChanged() const;
185
* Check if table frm has changed, for event TE_ALTER
187
bool tableFrmChanged() const;
190
* Check if table fragmentation has changed, for event TE_ALTER
192
bool tableFragmentationChanged() const;
195
* Check if table range partition list name has changed, for event TE_ALTER
197
bool tableRangeListChanged() const;
200
* Retrieve the GCI of the latest retrieved event
204
Uint64 getGCI() const;
207
* Retrieve the AnyValue of the latest retrieved event
211
Uint32 getAnyValue() const;
214
* Retrieve the complete GCI in the cluster (not necessarily
215
* associated with an event)
219
Uint64 getLatestGCI() const;
222
* Get the latest error
224
* @return Error object.
226
const struct NdbError & getNdbError() const;
228
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
229
/** these are subject to change at any time */
230
const NdbDictionary::Table* getTable() const;
231
const NdbDictionary::Event *getEvent() const;
232
const NdbRecAttr *getFirstPkAttr() const;
233
const NdbRecAttr *getFirstPkPreAttr() const;
234
const NdbRecAttr *getFirstDataAttr() const;
235
const NdbRecAttr *getFirstDataPreAttr() const;
237
// bool validateTable(NdbDictionary::Table &table) const;
239
void setCustomData(void * data);
240
void * getCustomData() const;
243
int hasError() const;
245
int getReqNodeId() const;
246
int getNdbdNodeId() const;
249
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
257
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
258
friend class NdbEventOperationImpl;
259
friend class NdbEventBuffer;
261
NdbEventOperation(Ndb *theNdb, const char* eventName);
262
~NdbEventOperation();
263
class NdbEventOperationImpl &m_impl;
264
NdbEventOperation(NdbEventOperationImpl& impl);
267
typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);