1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Mark Atwood
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.
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.
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
20
#include <drizzled/server_includes.h>
21
#include <drizzled/replicator.h>
22
#include <drizzled/gettext.h>
23
#include <drizzled/session.h>
25
int replicator_initializer(st_plugin_int *plugin)
30
if (p == NULL) return 1;
31
memset(p, 0, sizeof(replicator_t));
33
plugin->data= (void *)p;
35
if (plugin->plugin->init)
37
if (plugin->plugin->init((void *)p))
39
/* TRANSLATORS: The leading word "replicator" is the name
40
of the plugin api, and so should not be translated. */
41
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' init() failed"),
53
int replicator_finalizer(st_plugin_int *plugin)
55
replicator_t *p= (replicator_t *) plugin->data;
57
if (plugin->plugin->deinit)
59
if (plugin->plugin->deinit((void *)p))
61
/* TRANSLATORS: The leading word "replicator" is the name
62
of the plugin api, and so should not be translated. */
63
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' deinit() failed"),
73
/* This gets called by plugin_foreach once for each loaded replicator plugin */
74
static bool replicator_session_iterate(Session *session, plugin_ref plugin, void *)
76
replicator_t *repl= plugin_data(plugin, replicator_t *);
79
/* call this loaded replicator plugin's replicator_func1 function pointer */
80
if (repl && repl->session_init)
82
error= repl->session_init(session);
85
/* TRANSLATORS: The leading word "replicator" is the name
86
of the plugin api, and so should not be translated. */
87
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' session_init() failed"),
88
(char *)plugin_name(plugin));
97
This call is called once at the begining of each transaction.
99
extern handlerton *binlog_hton;
100
bool replicator_session_init(Session *session)
104
if (session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
105
trans_register_ha(session, true, binlog_hton);
106
trans_register_ha(session, false, binlog_hton);
108
if (session->getReplicationData())
112
call replicator_session_iterate
113
once for each loaded replicator plugin
115
foreach_rv= plugin_foreach(session, replicator_session_iterate,
116
DRIZZLE_REPLICATOR_PLUGIN, NULL);
121
/* The plugin_foreach() iterator requires that we
122
convert all the parameters of a plugin api entry point
123
into just one single void ptr, plus the session.
124
So we will take all the additional paramters of replicator_do2,
125
and marshall them into a struct of this type, and
126
then just pass in a pointer to it.
128
enum repl_row_exec_t{
134
typedef struct replicator_row_parms_st
136
repl_row_exec_t type;
138
const unsigned char *before;
139
const unsigned char *after;
140
} replicator_row_parms_st;
143
/* This gets called by plugin_foreach once for each loaded replicator plugin */
144
static bool replicator_do_row_iterate (Session *session, plugin_ref plugin, void *p)
146
replicator_t *repl= plugin_data(plugin, replicator_t *);
147
replicator_row_parms_st *params= (replicator_row_parms_st *) p;
149
switch (params->type) {
151
if (repl && repl->row_insert)
153
if (repl->row_insert(session, params->table))
155
/* TRANSLATORS: The leading word "replicator" is the name
156
of the plugin api, and so should not be translated. */
157
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' row_insert() failed"),
158
(char *)plugin_name(plugin));
165
if (repl && repl->row_update)
167
if (repl->row_update(session, params->table, params->before, params->after))
169
/* TRANSLATORS: The leading word "replicator" is the name
170
of the plugin api, and so should not be translated. */
171
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' row_update() failed"),
172
(char *)plugin_name(plugin));
179
if (repl && repl->row_delete)
181
if (repl->row_delete(session, params->table))
183
/* TRANSLATORS: The leading word "replicator" is the name
184
of the plugin api, and so should not be translated. */
185
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' row_delete() failed"),
186
(char *)plugin_name(plugin));
196
/* This is the replicator_do2 entry point.
197
This gets called by the rest of the Drizzle server code */
198
static bool replicator_do_row (Session *session, replicator_row_parms_st *params)
202
foreach_rv= plugin_foreach(session, replicator_do_row_iterate,
203
DRIZZLE_REPLICATOR_PLUGIN, params);
207
bool replicator_write_row(Session *session, Table *table)
209
replicator_row_parms_st param;
211
param.type= repl_insert;
216
return replicator_do_row(session, ¶m);
219
bool replicator_update_row(Session *session, Table *table,
220
const unsigned char *before,
221
const unsigned char *after)
223
replicator_row_parms_st param;
225
param.type= repl_update;
228
param.before= before;
230
return replicator_do_row(session, ¶m);
233
bool replicator_delete_row(Session *session, Table *table)
235
replicator_row_parms_st param;
237
param.type= repl_delete;
242
return replicator_do_row(session, ¶m);
248
Ok, not so much dragons, but this is where we handle either commits or rollbacks of
251
typedef struct replicator_row_end_st
255
} replicator_row_end_st;
257
/* We call this to end a statement (on each registered plugin) */
258
static bool replicator_end_transaction_iterate (Session *session, plugin_ref plugin, void *p)
260
replicator_t *repl= plugin_data(plugin, replicator_t *);
261
replicator_row_end_st *params= (replicator_row_end_st *)p;
263
/* call this loaded replicator plugin's replicator_func1 function pointer */
264
if (repl && repl->end_transaction)
266
if (repl->end_transaction(session, params->autocommit, params->commit))
268
/* TRANSLATORS: The leading word "replicator" is the name
269
of the plugin api, and so should not be translated. */
270
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' end_transaction() failed"),
271
(char *)plugin_name(plugin));
279
bool replicator_end_transaction(Session *session, bool autocommit, bool commit)
282
replicator_row_end_st params;
284
params.autocommit= autocommit;
285
params.commit= commit;
287
/* We need to free any data we did an init of for the session */
288
foreach_rv= plugin_foreach(session, replicator_end_transaction_iterate,
289
DRIZZLE_REPLICATOR_PLUGIN, (void *) ¶ms);
295
If you can do real 2PC this is your hook poing to know that the event is coming.
297
Always true for the moment.
300
bool replicator_prepare(Session *)
308
typedef struct replicator_statement_st
312
} replicator_statement_st;
314
/* We call this to end a statement (on each registered plugin) */
315
static bool replicator_statement_iterate(Session *session, plugin_ref plugin, void *p)
317
replicator_t *repl= plugin_data(plugin, replicator_t *);
318
replicator_statement_st *params= (replicator_statement_st *)p;
320
/* call this loaded replicator plugin's replicator_func1 function pointer */
321
if (repl && repl->statement)
323
if (repl->statement(session, params->query, params->query_length))
325
/* TRANSLATORS: The leading word "replicator" is the name
326
of the plugin api, and so should not be translated. */
327
errmsg_printf(ERRMSG_LVL_ERROR, _("replicator plugin '%s' statement() failed"),
328
(char *)plugin_name(plugin));
336
bool replicator_statement(Session *session, const char *query, size_t query_length)
339
replicator_statement_st params;
342
params.query_length= query_length;
344
/* We need to free any data we did an init of for the session */
345
foreach_rv= plugin_foreach(session, replicator_statement_iterate,
346
DRIZZLE_REPLICATOR_PLUGIN, (void *) ¶ms);