transactd 3.4.1 → 3.5.0

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +2 -2
  3. data/bin/common/tdclc_32_3_5.dll +0 -0
  4. data/bin/common/tdclc_64_3_5.dll +0 -0
  5. data/build/common/options.cmake +12 -0
  6. data/build/common/transactd_cl_common.cmake +1 -0
  7. data/build/common/transactd_required.cmake +5 -0
  8. data/build/swig/ruby/tdclrb_wrap.cpp +1029 -130
  9. data/build/swig/tdcl.i +60 -5
  10. data/build/tdclc/CMakeLists.txt +30 -32
  11. data/build/tdclc/libtdclcm.map +1 -1
  12. data/build/tdclc/tdclc.cbproj +1 -1
  13. data/build/tdclc/tdclc.rc +4 -4
  14. data/build/tdclcpp/CMakeLists.txt +39 -48
  15. data/build/tdclcpp/tdclcpp.rc +4 -4
  16. data/build/tdclcpp/tdclcpp_bc.cbproj +4 -1
  17. data/build/tdclrb/CMakeLists.txt +5 -4
  18. data/build/tdclrb/tdclrb.rc +4 -4
  19. data/source/bzs/db/engine/mysql/database.cpp +45 -35
  20. data/source/bzs/db/engine/mysql/database.h +6 -8
  21. data/source/bzs/db/engine/mysql/dbManager.cpp +11 -0
  22. data/source/bzs/db/engine/mysql/dbManager.h +1 -0
  23. data/source/bzs/db/engine/mysql/ha.cpp +174 -0
  24. data/source/bzs/db/engine/mysql/ha.h +50 -0
  25. data/source/bzs/db/engine/mysql/mysqlInternal.h +18 -1
  26. data/source/bzs/db/engine/mysql/mysqlProtocol.cpp +222 -9
  27. data/source/bzs/db/engine/mysql/mysqlProtocol.h +5 -0
  28. data/source/bzs/db/protocol/tdap/client/client.cpp +23 -9
  29. data/source/bzs/db/protocol/tdap/client/client.h +125 -94
  30. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +139 -30
  31. data/source/bzs/db/protocol/tdap/client/connMgr.h +40 -8
  32. data/source/bzs/db/protocol/tdap/client/database.cpp +17 -17
  33. data/source/bzs/db/protocol/tdap/client/database.h +15 -0
  34. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +10 -4
  35. data/source/bzs/db/protocol/tdap/client/haNameResolver.cpp +486 -0
  36. data/source/bzs/db/protocol/tdap/client/haNameResolver.h +74 -0
  37. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +102 -71
  38. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +15 -3
  39. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +2 -5
  40. data/source/bzs/db/protocol/tdap/client/nsTable.h +2 -1
  41. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -2
  42. data/source/bzs/db/protocol/tdap/client/table.cpp +1 -2
  43. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +13 -0
  44. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +1 -0
  45. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +9 -7
  46. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +2 -2
  47. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +328 -117
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +7 -8
  49. data/source/bzs/db/protocol/tdap/tdapcapi.h +81 -41
  50. data/source/bzs/db/transactd/connManager.cpp +118 -93
  51. data/source/bzs/db/transactd/connManager.h +6 -1
  52. data/source/bzs/db/transactd/connectionRecord.h +27 -7
  53. data/source/bzs/db/transactd/transactd.cpp +24 -13
  54. data/source/bzs/env/crosscompile.h +2 -0
  55. data/source/bzs/netsvc/client/iconnection.h +2 -0
  56. data/source/bzs/netsvc/client/tcpClient.cpp +45 -14
  57. data/source/bzs/netsvc/client/tcpClient.h +21 -4
  58. data/source/bzs/netsvc/server/IAppModule.h +1 -0
  59. data/source/bzs/netsvc/server/serverCpt.cpp +1 -1
  60. data/source/bzs/netsvc/server/serverPipe.cpp +2 -0
  61. data/source/bzs/netsvc/server/serverTpool.cpp +3 -5
  62. data/source/bzs/test/tdclatl/test_v3.js +91 -3
  63. data/source/bzs/test/tdclphp/transactd_v3_Test.php +89 -3
  64. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +69 -2
  65. data/source/bzs/test/trdclengn/testField.h +19 -1
  66. data/source/bzs/test/trdclengn/test_tdclcpp_ha.cpp +388 -0
  67. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +6 -1
  68. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1 -0
  69. data/source/bzs/test/trdclengn/testbase.h +7 -1
  70. data/source/global/replication/haCommand.cpp +843 -0
  71. data/source/global/replication/haCommand.h +78 -0
  72. data/source/global/replication/haMgr.cpp +321 -0
  73. data/source/global/replication/replCommand.cpp +696 -0
  74. data/source/global/replication/replCommand.h +161 -0
  75. data/source/global/tdclatl/BinlogPos.cpp +10 -0
  76. data/source/global/tdclatl/BinlogPos.h +1 -0
  77. data/source/global/tdclatl/ConnMgr.cpp +89 -2
  78. data/source/global/tdclatl/ConnMgr.h +13 -1
  79. data/source/global/tdclatl/ConnRecord.cpp +8 -2
  80. data/source/global/tdclatl/ConnRecord.h +4 -3
  81. data/source/global/tdclatl/Database.cpp +13 -0
  82. data/source/global/tdclatl/Database.h +2 -0
  83. data/source/global/tdclatl/HaNameREsolver.cpp +54 -0
  84. data/source/global/tdclatl/HaNameREsolver.h +68 -0
  85. data/source/global/tdclatl/resource.h +0 -0
  86. data/source/global/tdclatl/tdclatl.idl +76 -5
  87. metadata +16 -6
  88. data/bin/common/tdclc_32_3_4.dll +0 -0
  89. data/bin/common/tdclc_64_3_4.dll +0 -0
  90. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +0 -423
  91. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +0 -116
@@ -36,7 +36,9 @@
36
36
  #include <pthread.h>
37
37
  #endif
38
38
 
39
- extern bzs::netsvc::client::connections* m_cons;
39
+ namespace bnet = bzs::netsvc::client;
40
+
41
+ extern bnet::connections* m_cons;
40
42
 
41
43
  namespace bzs
42
44
  {
@@ -96,16 +98,16 @@ class client
96
98
  return true;
97
99
  }
98
100
 
99
- inline bzs::netsvc::client::connection* con() { return m_req.cid->con; };
101
+ inline bnet::connection* con() { return m_req.cid->con; };
100
102
 
101
- inline void setCon(bzs::netsvc::client::connection* con)
103
+ inline void setCon(bnet::connection* con)
102
104
  {
103
105
  m_req.cid->con = con;
104
106
  }
105
107
 
106
108
  inline void disconnect()
107
109
  {
108
- bzs::netsvc::client::connection* c = con();
110
+ bnet::connection* c = con();
109
111
  if (!c)
110
112
  m_req.result = 1;
111
113
  else
@@ -151,7 +153,7 @@ class client
151
153
  static void addSecondCharsetData(unsigned int destCodePage,
152
154
  std::string& src);
153
155
 
154
- bool handshake(bzs::netsvc::client::connection* c)
156
+ bool handshake(bnet::connection* c)
155
157
  {
156
158
  //Implements handshake here
157
159
  handshale_t* hst = (handshale_t*)c->read();
@@ -170,6 +172,17 @@ class client
170
172
  c->setCharsetServer(mysql::charsetIndex(hst->ver.cherserServer));
171
173
  m_req.cid->lock_wait_timeout = hst->lock_wait_timeout;
172
174
  m_req.cid->transaction_isolation = hst->transaction_isolation;
175
+ if (c->userOptions() & CL_OPTION_CHECK_ROLE)
176
+ {
177
+ bool clRoleMaster = (c->userOptions() & HST_OPTION_ROLE_MASTER) != 0;
178
+ bool srvRoleMaster = (hst->options & HST_OPTION_ROLE_MASTER) != 0;
179
+
180
+ if (clRoleMaster != srvRoleMaster)
181
+ {
182
+ m_preResult = ERROR_TD_INVALID_SERVER_ROLE;
183
+ return false;
184
+ }
185
+ }
173
186
  }
174
187
  if (auth)
175
188
  {
@@ -194,7 +207,7 @@ class client
194
207
  return true;
195
208
  }
196
209
 
197
- static bool handshakeCallback(bzs::netsvc::client::connection* c, void* data)
210
+ static bool handshakeCallback(bnet::connection* c, void* data)
198
211
  {
199
212
  return ((client*)data)->handshake(c);
200
213
  }
@@ -275,26 +288,51 @@ public:
275
288
  return false;
276
289
  }
277
290
 
278
- inline void connect()
291
+ inline bnet::connection* doConnect(endpoint_t& ep, bool newConnection, bool clearNRCache)
292
+ {
293
+ bnet::connection* c =
294
+ m_cons->connect(ep.host, ep.port,
295
+ client::handshakeCallback, this, newConnection, clearNRCache);
296
+ if (c)
297
+ {
298
+ setCon(c);
299
+ m_connecting = true;
300
+ }
301
+ return c;
302
+ }
303
+
304
+ bnet::connection* connect(bool newConnection = false)
279
305
  {
306
+ bnet::connection* c = NULL;
307
+ short errorOffset = 0;
280
308
  if (!m_req.cid->con)
281
309
  {
282
310
  m_preResult = 0;
311
+ m_connecting = false;
283
312
  endpoint_t ep;
284
313
  endPoint((const char*)m_req.keybuf, &ep);
285
314
  if (ep.host[0] == 0x00)
315
+ {
286
316
  m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
287
- bzs::netsvc::client::connection* c = m_cons->connect(ep.host, ep.port,
288
- client::handshakeCallback, this);
289
- if (c)
317
+ return c;
318
+ }
319
+ c = doConnect(ep, newConnection, false);
320
+ if (!c)
290
321
  {
291
- setCon(c);
292
- m_connecting = true;
322
+ if (m_cons->haNameResolver() &&
323
+ (m_preResult == 0 || m_preResult == ERROR_TD_INVALID_SERVER_ROLE))
324
+ {
325
+ m_preResult = 0;
326
+ c = doConnect(ep, newConnection, true);
327
+ errorOffset = ERROR_TD_RECONNECTED_OFFSET;
328
+ }
293
329
  }
294
- else if (m_preResult == 0)
295
- m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
330
+ if (!c && (m_preResult == 0))
331
+ m_preResult = errorCode(m_cons->connectError());
332
+ if (m_preResult) m_preResult += errorOffset;
296
333
  }
297
334
  m_disconnected = !m_req.cid->con;
335
+ return c;
298
336
  }
299
337
 
300
338
  inline void createIndex()
@@ -306,15 +344,18 @@ public:
306
344
  }
307
345
  m_req.paramMask = P_MASK_NOKEYBUF;
308
346
  int charsetIndexServer = getServerCharsetIndex();
309
- unsigned char keynum = m_req.keyNum;
310
- bool specifyKeyNum = (keynum >= 0x80);
311
- if (keynum >= 0x80)
312
- keynum -= 0x80;
313
- m_sql = sqlBuilder::sqlCreateIndex((tabledef*)m_req.data, keynum,
314
- specifyKeyNum, charsetIndexServer, ver());
315
- m_req.data = (ushort_td*)m_sql.c_str();
316
- m_tmplen = (uint_td)(m_sql.size() + 1);
317
- m_req.datalen = &m_tmplen;
347
+ if (charsetIndexServer != -1)
348
+ {
349
+ unsigned char keynum = m_req.keyNum;
350
+ bool specifyKeyNum = (keynum >= 0x80);
351
+ if (keynum >= 0x80)
352
+ keynum -= 0x80;
353
+ m_sql = sqlBuilder::sqlCreateIndex((tabledef*)m_req.data, keynum,
354
+ specifyKeyNum, charsetIndexServer, ver());
355
+ m_req.data = (ushort_td*)m_sql.c_str();
356
+ m_tmplen = (uint_td)(m_sql.size() + 1);
357
+ m_req.datalen = &m_tmplen;
358
+ }
318
359
  }
319
360
 
320
361
  inline void getSqlCreate(int charsetIndex = -1)
@@ -327,18 +368,20 @@ public:
327
368
  _TCHAR tmp[MAX_PATH*2]={0};
328
369
  stripAuth((const char*)m_req.keybuf, tmp, MAX_PATH);
329
370
  std::string name = getTableName(tmp);
330
- if (charsetIndex == -1)
331
- charsetIndex = getServerCharsetIndex();
332
- std::string sql = sqlBuilder::sqlCreateTable(name.c_str(), (tabledef*)m_req.data,
333
- charsetIndex, ver());
334
- uint_td datalen = *m_req.datalen;
335
- *m_req.datalen = (uint_td)(sql.size() + 1);
336
- if (datalen <= sql.size())
371
+ charsetIndex = getServerCharsetIndex();
372
+ if (charsetIndex != -1)
337
373
  {
338
- m_req.result = STATUS_BUFFERTOOSMALL;
339
- return;
374
+ std::string sql = sqlBuilder::sqlCreateTable(name.c_str(), (tabledef*)m_req.data,
375
+ charsetIndex, ver());
376
+ uint_td datalen = *m_req.datalen;
377
+ *m_req.datalen = (uint_td)(sql.size() + 1);
378
+ if (datalen <= sql.size())
379
+ {
380
+ m_req.result = STATUS_BUFFERTOOSMALL;
381
+ return;
382
+ }
383
+ strcpy_s((char*)m_req.data, *m_req.datalen, sql.c_str());
340
384
  }
341
- strcpy_s((char*)m_req.data, *m_req.datalen, sql.c_str());
342
385
  }
343
386
 
344
387
  inline void create()
@@ -353,51 +396,52 @@ public:
353
396
  stripAuth((const char*)m_req.keybuf, tmp, MAX_PATH);
354
397
  m_req.paramMask &= ~P_MASK_POSBLK;
355
398
  std::string name = getTableName(tmp);
356
- int charsetIndexServer = getServerCharsetIndex();
357
- if (!ver())
358
- {
359
- m_preResult = ERROR_TD_NOT_CONNECTED;
360
- return;
361
- }
362
- if ((m_req.keyNum == CR_SUBOP_BY_TABLEDEF) ||
363
- (m_req.keyNum == CR_SUBOP_BY_TABLEDEF_NOCKECK)) // make by tabledef
399
+ int charsetIndexServer = getServerCharsetIndex();
400
+ if (charsetIndexServer != -1)
364
401
  {
365
- m_sql = sqlBuilder::sqlCreateTable(name.c_str(), (tabledef*)m_req.data,
366
- charsetIndexServer, ver());
367
- m_req.keyNum -= 2; // -1= exists check 0 = no exists check
368
- }
369
- else if ((m_req.keyNum == CR_SUBOP_BY_SQL) ||
370
- (m_req.keyNum == CR_SUBOP_BY_SQL_NOCKECK)) // make by sql
371
- {
372
- m_req.keyNum -= 4; // -1= exists check 0 = no exists check
373
- if (charsetIndexServer != CHARSET_UTF8 && charsetIndexServer != CHARSET_UTF8B4)
374
- m_sql = sqlBuilder::convertString(mysql::codePage(charsetIndexServer), 65001,
375
- (const char*)m_req.data);
402
+ if ((m_req.keyNum == CR_SUBOP_BY_TABLEDEF) ||
403
+ (m_req.keyNum == CR_SUBOP_BY_TABLEDEF_NOCKECK)) // make by tabledef
404
+ {
405
+ m_sql = sqlBuilder::sqlCreateTable(name.c_str(), (tabledef*)m_req.data,
406
+ charsetIndexServer, ver());
407
+ m_req.keyNum -= 2; // -1= exists check 0 = no exists check
408
+ }
409
+ else if ((m_req.keyNum == CR_SUBOP_BY_SQL) ||
410
+ (m_req.keyNum == CR_SUBOP_BY_SQL_NOCKECK)) // make by sql
411
+ {
412
+ m_req.keyNum -= 4; // -1= exists check 0 = no exists check
413
+ if (charsetIndexServer != CHARSET_UTF8 && charsetIndexServer != CHARSET_UTF8B4)
414
+ m_sql = sqlBuilder::convertString(mysql::codePage(charsetIndexServer), 65001,
415
+ (const char*)m_req.data);
416
+ else
417
+ m_sql = (const char*)m_req.data;
418
+ }
376
419
  else
377
- m_sql = (const char*)m_req.data;
420
+ m_sql = sqlBuilder::sqlCreateTable(name.c_str(), (fileSpec*)m_req.data,
421
+ charsetIndexServer, ver());
422
+ m_req.data = (ushort_td*)m_sql.c_str();
423
+ m_tmplen = (uint_td)(m_sql.size() + 1);
424
+ m_req.datalen = &m_tmplen;
378
425
  }
379
- else
380
- m_sql = sqlBuilder::sqlCreateTable(name.c_str(), (fileSpec*)m_req.data,
381
- charsetIndexServer, ver());
382
- m_req.data = (ushort_td*)m_sql.c_str();
383
- m_tmplen = (uint_td)(m_sql.size() + 1);
384
- m_req.datalen = &m_tmplen;
385
426
  }
386
427
  else if ((m_req.keyNum == CR_SUBOP_SWAPNAME) ||
387
428
  (m_req.keyNum == CR_SUBOP_RENAME))
388
429
  {
389
430
  int charsetIndexServer = getServerCharsetIndex();
390
- m_sql = (char*)m_req.data;
391
- addSecondCharsetData(mysql::codePage(charsetIndexServer), m_sql);
392
- m_req.data = (ushort_td*)m_sql.c_str();
393
- m_tmplen = (uint_td)(m_sql.size() + 1);
394
- m_req.datalen = &m_tmplen;
431
+ if (charsetIndexServer != -1)
432
+ {
433
+ m_sql = (char*)m_req.data;
434
+ addSecondCharsetData(mysql::codePage(charsetIndexServer), m_sql);
435
+ m_req.data = (ushort_td*)m_sql.c_str();
436
+ m_tmplen = (uint_td)(m_sql.size() + 1);
437
+ m_req.datalen = &m_tmplen;
438
+ }
395
439
  }
396
440
  }
397
441
 
398
442
  inline void reconnect()
399
443
  {
400
- bzs::netsvc::client::connection* c = con();
444
+ bnet::connection* c = con();
401
445
  if (!c)
402
446
  {
403
447
  m_preResult = ERROR_TD_NOT_CONNECTED;
@@ -406,21 +450,25 @@ public:
406
450
  endpoint_t ep;
407
451
  endPoint((const char*)m_req.keybuf, &ep);
408
452
 
409
- m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
410
- if (ep.host[0] == 0x00) return;
411
-
453
+ if (ep.host[0] == 0x00)
454
+ {
455
+ m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
456
+ return;
457
+ }
458
+ //request req = m_req;
412
459
  if (!m_cons->reconnect(c, ep.host, ep.port, handshakeCallback, this))
413
460
  {
414
- m_preResult = errorCode(m_cons->connectError());
461
+ if (m_preResult == 0)
462
+ m_preResult = errorCode(m_cons->connectError());
415
463
  return;
416
464
  }
465
+ //m_req = req;
417
466
  m_connecting = true;
418
- if (getServerCharsetIndex() == -1)
419
- m_preResult = SERVER_CLIENT_NOT_COMPATIBLE;
420
- else
467
+ if (getServerCharsetIndex() != -1)
421
468
  {
422
469
  m_preResult = 0;
423
470
  buildDualChasetKeybuf();
471
+ m_disconnected = false;
424
472
  }
425
473
  m_req.paramMask = P_MASK_KEYONLY;
426
474
  }
@@ -436,34 +484,17 @@ public:
436
484
  else if ((m_req.keyNum == LG_SUBOP_CONNECT) ||
437
485
  (m_req.keyNum == LG_SUBOP_NEWCONNECT))
438
486
  {
439
- if (con())
440
- disconnect();
441
- endpoint_t ep;
442
- endPoint((const char*)m_req.keybuf, &ep);
443
- if (ep.host[0] == 0x00)
444
- m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
445
- bzs::netsvc::client::connection* c = m_cons->connect(
446
- ep.host, ep.port, handshakeCallback, this,
447
- (m_req.keyNum == LG_SUBOP_NEWCONNECT));
487
+ if (con()) disconnect();
488
+ bnet::connection* c =
489
+ connect((m_req.keyNum == LG_SUBOP_NEWCONNECT));
448
490
  if (c)
449
491
  {
450
- setCon(c); // if error throw exception
451
- m_connecting = true;
452
- if (getServerCharsetIndex() == -1)
453
- {
454
- if (c->error() || (m_req.resultLen == 0))
455
- m_preResult = ERROR_TD_INVALID_CLINETHOST;
456
- else
457
- m_preResult = SERVER_CLIENT_NOT_COMPATIBLE;
458
- }
459
- else
492
+ if (getServerCharsetIndex() != -1)
460
493
  {
461
494
  buildDualChasetKeybuf();
462
495
  m_disconnected = false;
463
496
  }
464
497
  }
465
- else
466
- m_preResult = errorCode(m_cons->connectError());
467
498
  }
468
499
  else if (m_req.keyNum == LG_SUBOP_DISCONNECT)
469
500
  {
@@ -485,7 +516,7 @@ public:
485
516
  {
486
517
  if (result() == 0)
487
518
  {
488
- bzs::netsvc::client::connection* c = con();
519
+ bnet::connection* c = con();
489
520
  if (!c)
490
521
  m_preResult = ERROR_TD_NOT_CONNECTED;
491
522
  else
@@ -51,10 +51,11 @@ static const _TCHAR* SYSVAR_NAME[TD_VAR_SIZE] =
51
51
  _T("use_piped_local"),
52
52
  _T("hs_port"),
53
53
  _T("use_handlersocket"),
54
- _T("timestamp_always)")
54
+ _T("timestamp_always"),
55
+ _T("startup_ha")
55
56
  };
56
57
 
57
- static const _TCHAR* STATUSVAR_NAME[TD_VAR_SIZE] =
58
+ static const _TCHAR* STATUSVAR_NAME[TD_SVAR_SIZE] =
58
59
  {
59
60
  _T("tcp_connections"),
60
61
  _T("tcp_wait_threads"),
@@ -63,6 +64,7 @@ static const _TCHAR* STATUSVAR_NAME[TD_VAR_SIZE] =
63
64
  _T("pipe_connections"),
64
65
  _T("pipe_wait_threads"),
65
66
  _T("cur_open_databases"),
67
+ _T("ha"),
66
68
  };
67
69
 
68
70
  static const _TCHAR* SLAVE_STATUS_NAME[SLAVE_STATUS_DEFAULT_SIZE] =
@@ -146,6 +148,14 @@ static const _TCHAR* SLAVE_STATUS_NAME_EX_MA[SLAVE_STATUS_EX_MA_SIZE] =
146
148
  _T("Gtid_Slave_Pos"),
147
149
  };
148
150
 
151
+ static const _TCHAR* EXTENDED_VAR_NAME[TD_EXTENDED_VAR_SIZE] =
152
+ {
153
+ _T("MySQL_Gtid_Mode"),
154
+ _T("Binlog_File"),
155
+ _T("Binlog_Position"),
156
+ _T("Executed_Gtid_Set/Gtid_Cur_Pos")
157
+ };
158
+
149
159
  class stringBuffer
150
160
  {
151
161
  friend class connMgr;
@@ -176,12 +186,12 @@ connRecords& connRecords::operator=(const connRecords& r)
176
186
 
177
187
  void connRecords::clear() { m_records.clear(); m_buf.reset(); }
178
188
 
179
- const connRecords::record& connRecords::operator[] (int index) const
189
+ const connRecords::record& connRecords::operator[] (size_t index) const
180
190
  {
181
191
  return m_records[index];
182
192
  }
183
193
 
184
- connRecords::record& connRecords::operator[] (int index)
194
+ connRecords::record& connRecords::operator[] (size_t index)
185
195
  {
186
196
  return m_records[index];
187
197
  }
@@ -190,6 +200,8 @@ size_t connRecords::size() const { return m_records.size(); }
190
200
 
191
201
  connRecords* connRecords::create(){ return new connRecords();}
192
202
 
203
+ connRecords* connRecords::create(const connRecords& r){ return new connRecords(r);}
204
+
193
205
  void connRecords::release(){ delete this;}
194
206
 
195
207
  //-----------------------------------------------------------------------------
@@ -233,9 +245,10 @@ connMgr::connMgr(database* db) : nstable(db)
233
245
  m_params[0] = 0;
234
246
  m_params[1] = 0;
235
247
  m_keylen = sizeof(m_params);
248
+ m_datalen = m_buflen = 0;
236
249
  }
237
250
 
238
- connMgr::~connMgr() {}
251
+ connMgr::~connMgr() {setIsOpen(false);}
239
252
 
240
253
  database* connMgr::db() const
241
254
  {
@@ -277,6 +290,7 @@ bool connMgr::connect(const _TCHAR* uri)
277
290
  m_stat = m_db->stat();
278
291
  if (m_stat == 0)
279
292
  {
293
+ setIsOpen(true);
280
294
  m_uri = uri;
281
295
  btrVersions vs;
282
296
  m_db->getBtrVersion(&vs);
@@ -290,10 +304,13 @@ void connMgr::disconnect()
290
304
  {
291
305
  if (m_uri != _T(""))
292
306
  {
293
- m_db->disconnect(m_uri.c_str());
307
+ m_db->disconnect();
294
308
  m_stat = m_db->stat();
295
309
  if (m_stat == 0)
310
+ {
296
311
  m_uri = _T("");
312
+ setIsOpen(false);
313
+ }
297
314
  }
298
315
  }
299
316
 
@@ -311,8 +328,11 @@ void connMgr::allocBuffer()
311
328
  const connMgr::records& connMgr::getRecords(bool isInUseTable)
312
329
  {
313
330
  tdap(TD_STASTISTICS);
314
- if (m_stat == 0 && *((int*)m_keybuf) != (int)sizeof(connMgr::record))
315
- convertFromOldFormat(isInUseTable);
331
+ if (m_keynum < TD_STSTCS_SLAVE_STATUS)
332
+ {
333
+ if (m_stat == 0 && *((int*)m_keybuf) != (int)sizeof(connMgr::record))
334
+ convertFromOldFormat(isInUseTable);
335
+ }
316
336
  if (m_stat == 0)
317
337
  m_records.resize(m_datalen / sizeof(connMgr::record));
318
338
  else
@@ -388,22 +408,63 @@ void connMgr::setBlobFieldPointer(const blobHeader* hd)
388
408
  }
389
409
  }
390
410
 
391
- const connMgr::records& connMgr::slaveStatus()
411
+ const connMgr::records& connMgr::blobOperation(int op)
392
412
  {
393
413
  if ((m_pluginVer.majorVersion >= 3) && (m_pluginVer.minorVersion >= 2))
394
414
  {
395
- m_keynum = TD_STSTCS_SLAVE_STATUS;
415
+ m_keynum = op;
396
416
  allocBuffer();
397
417
  getRecords();
398
418
  // set blob pointers
399
419
  setBlobFieldPointer(getBlobHeader());
400
420
  return m_records;
401
- }
421
+ }
402
422
  m_stat = STATUS_NOSUPPORT_OP;
403
423
  m_records.resize(0);
404
424
  return m_records;
405
425
  }
406
426
 
427
+ const connMgr::records& connMgr::slaveStatus(const char* channel)
428
+ {
429
+ char ch[65] = {0};
430
+ if (channel)
431
+ strcpy_s(ch, 65, channel);
432
+ m_keybuf = (void*)ch;
433
+ m_keylen = 65;
434
+ blobOperation(TD_STSTCS_SLAVE_STATUS);
435
+ m_keybuf = &m_params[0];
436
+ m_keylen = sizeof(m_params);
437
+ return m_records;
438
+ }
439
+ #ifdef _UNICODE
440
+ const connMgr::records& connMgr::slaveStatus(const wchar_t* channel)
441
+ {
442
+ char tmp[128] = {0};
443
+ if (channel)
444
+ WideCharToMultiByte(CP_UTF8, 0, channel,-1, tmp, 128, NULL, NULL);
445
+ return slaveStatus(tmp);
446
+ }
447
+ #endif
448
+
449
+
450
+ const connMgr::records& connMgr::channels(bool withLock )
451
+ {
452
+ m_keynum = withLock ?
453
+ TD_STSTCS_SLAVE_CHANNELS_LOCK :TD_STSTCS_SLAVE_CHANNELS;
454
+ allocBuffer();
455
+ return getRecords();
456
+ }
457
+
458
+ const connMgr::records& connMgr::slaveHosts()
459
+ {
460
+ return blobOperation(TD_STSTCS_SLAVE_HOSTS);
461
+ }
462
+
463
+ const connMgr::records& connMgr::extendedvars()
464
+ {
465
+ return blobOperation(TD_STSTCS_EXTENDED_VARIABLES);
466
+ }
467
+
407
468
  const connMgr::records& connMgr::sysvars()
408
469
  {
409
470
  m_keynum = TD_STSTCS_SYSTEM_VARIABLES;
@@ -449,18 +510,59 @@ void connMgr::postDisconnectOne(__int64 connid)
449
510
  {
450
511
  m_keynum = TD_STSTCS_DISCONNECT_ONE;
451
512
  m_params[0] = connid;
513
+ m_datalen = 0;
452
514
  tdap(TD_STASTISTICS);
453
515
  }
454
516
 
455
517
  void connMgr::postDisconnectAll()
456
518
  {
457
519
  m_keynum = TD_STSTCS_DISCONNECT_ALL;
520
+ m_datalen = 0;
521
+ tdap(TD_STASTISTICS);
522
+ }
523
+
524
+ bool connMgr::haLock()
525
+ {
526
+ m_keynum = TD_STSTCS_HA_LOCK;
527
+ m_datalen = 0;
528
+ tdap(TD_STASTISTICS);
529
+ return stat() == 0;
530
+ }
531
+
532
+ void connMgr::haUnlock()
533
+ {
534
+ m_keynum = TD_STSTCS_HA_UNLOCK;
535
+ m_datalen = 0;
536
+ tdap(TD_STASTISTICS);
537
+
538
+ }
539
+
540
+ bool connMgr::setRole(int v)
541
+ {
542
+ m_keynum = (v == HA_ROLE_MASTER) ? TD_STSTCS_HA_SET_ROLEMASTER :
543
+ (v == HA_ROLE_SLAVE) ? TD_STSTCS_HA_SET_ROLESLAVE :
544
+ TD_STSTCS_HA_SET_ROLENONE;
545
+ m_datalen = 0;
458
546
  tdap(TD_STASTISTICS);
547
+ return stat() == 0;
459
548
  }
460
549
 
461
- short_td connMgr::stat()
550
+ bool connMgr::setTrxBlock(bool v)
462
551
  {
463
- return m_stat;
552
+ m_keynum = v ? TD_STSTCS_HA_SET_TRXBLOCK :
553
+ TD_STSTCS_HA_SET_TRXNOBLOCK;
554
+ m_datalen = 0;
555
+ tdap(TD_STASTISTICS);
556
+ return stat() == 0;
557
+ }
558
+
559
+ bool connMgr::setEnableFailover(bool v)
560
+ {
561
+ m_keynum = v ? TD_STSTCS_HA_ENABLE_FO :
562
+ TD_STSTCS_HA_DISBLE_FO;
563
+ m_datalen = 0;
564
+ tdap(TD_STASTISTICS);
565
+ return stat() == 0;
464
566
  }
465
567
 
466
568
  connMgr* connMgr::create(database* db)
@@ -480,37 +582,44 @@ void connMgr::removeSystemDb(connMgr::records& recs)
480
582
  }
481
583
  }
482
584
 
483
- const _TCHAR* connMgr::sysvarName(uint_td index)
585
+ const _TCHAR* connMgr::sysvarName(uint_td id)
484
586
  {
485
- if (index < TD_VAR_SIZE)
486
- return SYSVAR_NAME[index];
587
+ if (id < TD_VAR_SIZE)
588
+ return SYSVAR_NAME[id];
487
589
  return _T("");
488
590
  }
489
591
 
490
- const _TCHAR* connMgr::statusvarName(uint_td index)
592
+ const _TCHAR* connMgr::statusvarName(uint_td id)
491
593
  {
492
- if (index < TD_SVAR_SIZE)
493
- return STATUSVAR_NAME[index];
594
+ if (id < TD_SVAR_SIZE)
595
+ return STATUSVAR_NAME[id];
494
596
  return _T("");
495
597
  }
496
598
 
497
- const _TCHAR* slaveStatusName1(uint_td index)
599
+ const _TCHAR* slaveStatusName1(uint_td id)
498
600
  {
499
- if (index < SLAVE_STATUS_DEFAULT_SIZE)
500
- return SLAVE_STATUS_NAME[index];
601
+ if (id < SLAVE_STATUS_DEFAULT_SIZE)
602
+ return SLAVE_STATUS_NAME[id];
501
603
  return _T("");
502
604
  }
503
605
 
504
- const _TCHAR* connMgr::slaveStatusName(uint_td index) const
606
+ const _TCHAR* connMgr::slaveStatusName(uint_td id) const
505
607
  {
506
608
  bool mariadb = m_serverVer.isMariaDB();
507
- if (index < SLAVE_STATUS_DEFAULT_SIZE)
508
- return slaveStatusName1(index);
509
- index -= SLAVE_STATUS_DEFAULT_SIZE;
510
- if(mariadb && (index < SLAVE_STATUS_EX_MA_SIZE))
511
- return SLAVE_STATUS_NAME_EX_MA[index];
512
- else if(!mariadb && (index < SLAVE_STATUS_EX_SIZE))
513
- return SLAVE_STATUS_NAME_EX[index];
609
+ if (id < SLAVE_STATUS_DEFAULT_SIZE)
610
+ return slaveStatusName1(id);
611
+ id -= SLAVE_STATUS_DEFAULT_SIZE;
612
+ if(mariadb && (id < SLAVE_STATUS_EX_MA_SIZE))
613
+ return SLAVE_STATUS_NAME_EX_MA[id];
614
+ else if(!mariadb && (id < SLAVE_STATUS_EX_SIZE))
615
+ return SLAVE_STATUS_NAME_EX[id];
616
+ return _T("");
617
+ }
618
+
619
+ const _TCHAR* connMgr::extendedVarName(uint_td id)
620
+ {
621
+ if (id < TD_EXTENDED_VAR_SIZE)
622
+ return EXTENDED_VAR_NAME[id];
514
623
  return _T("");
515
624
  }
516
625