ruby-binlog 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +26 -13
- data/ext/ruby_binlog.cpp +121 -7
- data/ext/ruby_binlog.h +7 -0
- data/ext/ruby_binlog_cast_to_tcp_driver.cpp +18 -0
- metadata +5 -4
data/README
CHANGED
@@ -14,19 +14,32 @@ gem install ruby-binlog
|
|
14
14
|
|
15
15
|
require "binlog"
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
client.position = 4
|
17
|
+
master_log_file = "mysql-bin.000001"
|
18
|
+
master_log_pos = 4
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
begin
|
21
|
+
client = Binlog::Client.new("mysql://repl:repl@example.com")
|
22
|
+
sleep 0.3 until client.connect
|
23
|
+
client.set_position(master_log_file, master_log_pos)
|
24
|
+
|
25
|
+
while event = client.wait_for_next_event
|
26
|
+
master_log_pos = event.next_position
|
27
|
+
|
28
|
+
case event
|
29
|
+
when Binlog::QueryEvent
|
30
|
+
puts event.query
|
31
|
+
when Binlog::RowEvent
|
32
|
+
puts event.event_type
|
33
|
+
p event.columns
|
34
|
+
p event.rows
|
35
|
+
when Binlog::RotateEvent
|
36
|
+
master_log_file = event.binlog_file
|
37
|
+
else
|
38
|
+
puts "(#{event.event_type})"
|
39
|
+
end
|
31
40
|
end
|
41
|
+
rescue Binlog::Error => e
|
42
|
+
puts e
|
43
|
+
retry if client.closed?
|
44
|
+
raise e
|
32
45
|
end
|
data/ext/ruby_binlog.cpp
CHANGED
@@ -58,22 +58,116 @@ struct Client {
|
|
58
58
|
int result;
|
59
59
|
|
60
60
|
Data_Get_Struct(self, Client, p);
|
61
|
+
TRAP_BEG;
|
61
62
|
result = p->m_binlog->connect();
|
63
|
+
TRAP_END;
|
62
64
|
|
63
65
|
return (result == 0) ? Qtrue : Qfalse;
|
64
66
|
}
|
65
67
|
|
68
|
+
// XXX: Don't use
|
69
|
+
/*
|
70
|
+
static VALUE disconnect(VALUE self) {
|
71
|
+
Client *p;
|
72
|
+
mysql::system::Binlog_tcp_driver *driver;
|
73
|
+
|
74
|
+
Data_Get_Struct(self, Client, p);
|
75
|
+
driver = cast_to_tcp_driver(p->m_binlog->m_driver);
|
76
|
+
|
77
|
+
if (driver) {
|
78
|
+
driver->disconnect();
|
79
|
+
}
|
80
|
+
|
81
|
+
return Qnil;
|
82
|
+
}
|
83
|
+
*/
|
84
|
+
|
85
|
+
// XXX: Don't use
|
86
|
+
/*
|
87
|
+
static VALUE reconnect(VALUE self) {
|
88
|
+
Client *p;
|
89
|
+
mysql::system::Binlog_tcp_driver *driver;
|
90
|
+
|
91
|
+
Data_Get_Struct(self, Client, p);
|
92
|
+
driver = cast_to_tcp_driver(p->m_binlog->m_driver);
|
93
|
+
|
94
|
+
if (driver) {
|
95
|
+
driver->reconnect();
|
96
|
+
}
|
97
|
+
|
98
|
+
return Qnil;
|
99
|
+
}
|
100
|
+
*/
|
101
|
+
|
102
|
+
static VALUE is_closed(VALUE self) {
|
103
|
+
Client *p;
|
104
|
+
mysql::system::Binlog_tcp_driver *driver;
|
105
|
+
|
106
|
+
Data_Get_Struct(self, Client, p);
|
107
|
+
driver = cast_to_tcp_driver(p->m_binlog->m_driver);
|
108
|
+
|
109
|
+
if (!driver) {
|
110
|
+
return Qfalse;
|
111
|
+
}
|
112
|
+
|
113
|
+
if (driver->m_socket) {
|
114
|
+
bool socket_is_open;
|
115
|
+
|
116
|
+
TRAP_BEG;
|
117
|
+
socket_is_open = driver->m_socket->is_open();
|
118
|
+
TRAP_END;
|
119
|
+
|
120
|
+
return socket_is_open ? Qfalse : Qtrue;
|
121
|
+
} else {
|
122
|
+
return Qtrue;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
66
126
|
static VALUE wait_for_next_event(VALUE self) {
|
67
127
|
Client *p;
|
68
128
|
Binary_log_event *event;
|
69
|
-
int result;
|
129
|
+
int result = ERR_EOF;
|
70
130
|
VALUE retval = Qnil;
|
131
|
+
mysql::system::Binlog_tcp_driver *driver;
|
71
132
|
|
72
133
|
Data_Get_Struct(self, Client, p);
|
134
|
+
driver = cast_to_tcp_driver(p->m_binlog->m_driver);
|
135
|
+
|
136
|
+
if (driver) {
|
137
|
+
int closed = 0;
|
138
|
+
timeval interval = { 0, WAIT_INTERVAL };
|
139
|
+
|
140
|
+
TRAP_BEG;
|
141
|
+
while (1) {
|
142
|
+
if (driver->m_event_queue->is_not_empty()) {
|
143
|
+
result = p->m_binlog->wait_for_next_event(&event);
|
144
|
+
break;
|
145
|
+
} else {
|
146
|
+
if (driver->m_socket && driver->m_socket->is_open()) {
|
147
|
+
rb_thread_wait_for(interval);
|
148
|
+
} else {
|
149
|
+
closed = 1;
|
150
|
+
driver->shutdown();
|
151
|
+
rb_thread_wait_for(interval);
|
152
|
+
break;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
TRAP_END;
|
157
|
+
|
158
|
+
if (closed) {
|
159
|
+
TRAP_BEG;
|
160
|
+
driver->disconnect();
|
161
|
+
TRAP_END;
|
162
|
+
|
163
|
+
rb_raise(rb_eBinlogError, "MySQL server has gone away");
|
164
|
+
}
|
165
|
+
} else {
|
166
|
+
TRAP_BEG;
|
167
|
+
result = p->m_binlog->wait_for_next_event(&event);
|
168
|
+
TRAP_END;
|
169
|
+
}
|
73
170
|
|
74
|
-
TRAP_BEG;
|
75
|
-
result = p->m_binlog->wait_for_next_event(&event);
|
76
|
-
TRAP_END;
|
77
171
|
|
78
172
|
if (result == ERR_EOF) {
|
79
173
|
return Qfalse;
|
@@ -152,13 +246,17 @@ struct Client {
|
|
152
246
|
if (NIL_P(position)) {
|
153
247
|
unsigned long i_position;
|
154
248
|
i_position = NUM2ULONG(filename);
|
249
|
+
TRAP_BEG;
|
155
250
|
result = p->m_binlog->set_position(i_position);
|
251
|
+
TRAP_END;
|
156
252
|
} else {
|
157
253
|
unsigned long i_position;
|
158
254
|
Check_Type(filename, T_STRING);
|
159
255
|
i_position = NUM2ULONG(position);
|
160
256
|
std::string s_filename(StringValuePtr(filename));
|
257
|
+
TRAP_BEG;
|
161
258
|
result = p->m_binlog->set_position(s_filename, i_position);
|
259
|
+
TRAP_END;
|
162
260
|
}
|
163
261
|
|
164
262
|
switch (result) {
|
@@ -168,7 +266,7 @@ struct Client {
|
|
168
266
|
case ERR_EOF:
|
169
267
|
retval = Qfalse;
|
170
268
|
default:
|
171
|
-
rb_raise(
|
269
|
+
rb_raise(rb_eBinlogError, "An unspecified error occurred (%d)", result);
|
172
270
|
break;
|
173
271
|
}
|
174
272
|
|
@@ -181,7 +279,9 @@ struct Client {
|
|
181
279
|
int result;
|
182
280
|
|
183
281
|
Data_Get_Struct(self, Client, p);
|
282
|
+
TRAP_BEG;
|
184
283
|
result = p->m_binlog->set_position(NUM2ULONG(position));
|
284
|
+
TRAP_END;
|
185
285
|
|
186
286
|
switch (result) {
|
187
287
|
case ERR_OK:
|
@@ -190,7 +290,7 @@ struct Client {
|
|
190
290
|
case ERR_EOF:
|
191
291
|
retval = Qfalse;
|
192
292
|
default:
|
193
|
-
rb_raise(
|
293
|
+
rb_raise(rb_eBinlogError, "An unspecified error occurred (%d)", result);
|
194
294
|
break;
|
195
295
|
}
|
196
296
|
|
@@ -210,7 +310,9 @@ struct Client {
|
|
210
310
|
} else {
|
211
311
|
Check_Type(filename, T_STRING);
|
212
312
|
std::string s_filename(StringValuePtr(filename));
|
313
|
+
TRAP_BEG;
|
213
314
|
position = p->m_binlog->get_position(s_filename);
|
315
|
+
TRAP_END;
|
214
316
|
}
|
215
317
|
|
216
318
|
return ULONG2NUM(position);
|
@@ -219,7 +321,13 @@ struct Client {
|
|
219
321
|
static VALUE get_position2(VALUE self) {
|
220
322
|
Client *p;
|
221
323
|
Data_Get_Struct(self, Client, p);
|
222
|
-
|
324
|
+
unsigned long position;
|
325
|
+
|
326
|
+
TRAP_BEG;
|
327
|
+
position = p->m_binlog->get_position();
|
328
|
+
TRAP_END;
|
329
|
+
|
330
|
+
return ULONG2NUM(position);
|
223
331
|
}
|
224
332
|
|
225
333
|
static void init() {
|
@@ -227,6 +335,10 @@ struct Client {
|
|
227
335
|
rb_define_alloc_func(rb_cBinlogClient, &alloc);
|
228
336
|
rb_define_private_method(rb_cBinlogClient, "initialize", __F(&initialize), 1);
|
229
337
|
rb_define_method(rb_cBinlogClient, "connect", __F(&connect), 0);
|
338
|
+
// XXX: Don't use
|
339
|
+
//rb_define_method(rb_cBinlogClient, "disconnect", __F(&disconnect), 0);
|
340
|
+
//rb_define_method(rb_cBinlogClient, "reconnect", __F(&reconnect), 0);
|
341
|
+
rb_define_method(rb_cBinlogClient, "closed?", __F(&is_closed), 0);
|
230
342
|
rb_define_method(rb_cBinlogClient, "wait_for_next_event", __F(&wait_for_next_event), 0);
|
231
343
|
rb_define_method(rb_cBinlogClient, "set_position", __F(&set_position), -1);
|
232
344
|
rb_define_method(rb_cBinlogClient, "position=", __F(&set_position2), 1);
|
@@ -240,10 +352,12 @@ struct Client {
|
|
240
352
|
|
241
353
|
VALUE rb_mBinlog;
|
242
354
|
VALUE rb_cBinlogEvent;
|
355
|
+
VALUE rb_eBinlogError;
|
243
356
|
|
244
357
|
void Init_binlog() {
|
245
358
|
rb_mBinlog = rb_define_module("Binlog");
|
246
359
|
rb_cBinlogEvent = rb_define_class_under(rb_mBinlog, "Event", rb_cObject);
|
360
|
+
rb_eBinlogError = rb_define_class_under(rb_mBinlog, "Error", rb_eRuntimeError);
|
247
361
|
|
248
362
|
rb_define_const(rb_cBinlogEvent, "UNKNOWN_EVENT", INT2NUM(0));
|
249
363
|
rb_define_const(rb_cBinlogEvent, "START_EVENT_V3", INT2NUM(1));
|
data/ext/ruby_binlog.h
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#ifndef __RUBY_BINLOG_H__
|
2
2
|
#define __RUBY_BINLOG_H__
|
3
3
|
|
4
|
+
// XXX:
|
5
|
+
#define private public
|
6
|
+
|
4
7
|
#include <string>
|
5
8
|
#include <binlog_api.h>
|
6
9
|
#include <ruby.h>
|
@@ -21,11 +24,15 @@
|
|
21
24
|
#define __F(f) (reinterpret_cast<VALUE (*)(...)>(f))
|
22
25
|
#endif
|
23
26
|
|
27
|
+
#define WAIT_INTERVAL 300
|
28
|
+
|
24
29
|
extern VALUE rb_mBinlog;
|
30
|
+
extern VALUE rb_eBinlogError;
|
25
31
|
|
26
32
|
namespace ruby {
|
27
33
|
namespace binlog {
|
28
34
|
const char* get_field_type_str(mysql::system::enum_field_types type);
|
35
|
+
mysql::system::Binlog_tcp_driver *cast_to_tcp_driver(mysql::system::Binary_log_driver *driver);
|
29
36
|
} // namespace binlog
|
30
37
|
} // namespace ruby
|
31
38
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#include "ruby_binlog.h"
|
2
|
+
|
3
|
+
namespace ruby {
|
4
|
+
namespace binlog {
|
5
|
+
|
6
|
+
mysql::system::Binlog_tcp_driver *cast_to_tcp_driver(mysql::system::Binary_log_driver *driver) {
|
7
|
+
const char *cname = typeid(*driver).name();
|
8
|
+
std::string name = cname;
|
9
|
+
|
10
|
+
if(name.find("tcp_driver") == std::string::npos) {
|
11
|
+
return 0;
|
12
|
+
}
|
13
|
+
|
14
|
+
return static_cast<mysql::system::Binlog_tcp_driver *>(driver);
|
15
|
+
}
|
16
|
+
|
17
|
+
} // namespace binlog
|
18
|
+
} // namespace ruby
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-binlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- winebarrel
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-08-
|
18
|
+
date: 2012-08-28 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Ruby binding for MySQL Binary log API.
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- ext/ruby_binlog_xid_event.cpp
|
31
31
|
- ext/ruby_binlog_rotate_event.cpp
|
32
32
|
- ext/ruby_binlog_format_event.cpp
|
33
|
+
- ext/ruby_binlog_cast_to_tcp_driver.cpp
|
33
34
|
- ext/ruby_binlog_user_var_event.cpp
|
34
35
|
- ext/ruby_binlog.cpp
|
35
36
|
- ext/ruby_binlog_table_map_event.cpp
|