ruby-binlog 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -14,19 +14,32 @@ gem install ruby-binlog
14
14
 
15
15
  require "binlog"
16
16
 
17
- client = Binlog::Client.new("mysql://repl:repl@nyarlathotep")
18
- client.connect
19
- client.position = 4
17
+ master_log_file = "mysql-bin.000001"
18
+ master_log_pos = 4
20
19
 
21
- while event = client.wait_for_next_event
22
- case event
23
- when Binlog::QueryEvent
24
- puts event.query
25
- when Binlog::RowEvent
26
- puts event.event_type
27
- p event.columns
28
- p event.rows
29
- else
30
- puts "(#{event.event_type})"
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(rb_eRuntimeError, "An unspecified error occurred (%d)", result);
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(rb_eRuntimeError, "An unspecified error occurred (%d)", result);
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
- return ULONG2NUM(p->m_binlog->get_position());
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: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 4
10
- version: 0.1.4
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-26 00:00:00 Z
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