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
@@ -920,16 +920,13 @@ void nstable::tdap(ushort_td op)
920
920
  Sleep(m_impl->nsdb->lockWaitTime());
921
921
  break;
922
922
  default:
923
- #ifdef TEST_RECONNECT
924
- if (canRecoverNetError(m_stat))
923
+ if (nsdatabase::enableAutoReconnect() && canRecoverNetError(m_stat))
925
924
  {
926
- m_impl->nsdb->reconnect();
927
- if (m_stat) return;
925
+ if (!m_impl->nsdb->reconnect()) return;
928
926
  m_stat = ERROR_TD_NET_TIMEOUT;
929
927
  LoopCount = -1;
930
928
  break;
931
929
  }
932
- #endif
933
930
  return;
934
931
  }
935
932
  } while ((m_stat != STATUS_SUCCESS) &&
@@ -23,6 +23,7 @@
23
23
  #include <bzs/db/protocol/tdap/tdapSchema.h>
24
24
  #include <bzs/rtl/exception.h>
25
25
  #include "export.h"
26
+ #include <limits.h>
26
27
 
27
28
  namespace bzs
28
29
  {
@@ -193,7 +194,7 @@ public:
193
194
  return retbuf;
194
195
  }
195
196
 
196
- void beginBulkInsert(int maxBuflen);
197
+ void beginBulkInsert(int maxBuflen=BULKBUFSIZE);
197
198
  void abortBulkInsert() { doAbortBulkInsert(); }
198
199
  inline ushort_td commitBulkInsert(bool autoCommit = false)
199
200
  {
@@ -324,7 +324,7 @@ std::string sqlBuilder::getFieldList(const tabledef* table, std::vector<std::str
324
324
  }else if (fd.type == ft_bit)
325
325
  {
326
326
  s += " NULL DEFAULT b'";
327
- char tmp[100] = {NULL};
327
+ char tmp[100] = {0};
328
328
  s += getBitDefalutValue(tmp, 100, (unsigned __int64)fd.defaultValue64());
329
329
  s += "'";
330
330
  }
@@ -369,7 +369,7 @@ std::string sqlBuilder::getFieldList(const tabledef* table, std::vector<std::str
369
369
  }else if (fd.type == ft_bit)
370
370
  {
371
371
  s += "DEFAULT b'";
372
- char tmp[100] = {NULL};
372
+ char tmp[100] = {0};
373
373
  s += getBitDefalutValue(tmp, 100, (unsigned __int64)fd.defaultValue());
374
374
  s += "'";
375
375
  }
@@ -631,7 +631,6 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
631
631
  uint_td result = 0;
632
632
  client::filter* filter = m_impl->filterPtr.get();
633
633
 
634
-
635
634
  if (filter)
636
635
  {
637
636
  struct smartChangePreparedId
@@ -1544,7 +1543,7 @@ void table::doInit(tabledef** Def, short fnum, bool /*regularDir*/, bool mysqlnu
1544
1543
 
1545
1544
  keylen_td table::writeKeyDataTo(uchar_td* to, int keySize)
1546
1545
  {
1547
- if ((*m_tableDef)->keyCount)
1546
+ if ((*m_tableDef)->keyCount && m_keynum >= 0)
1548
1547
  {
1549
1548
  keydef& keydef =
1550
1549
  (*m_tableDef)->keyDefs[(int)m_impl->keyNumIndex[(int)m_keynum]];
@@ -968,6 +968,19 @@ inline void convertTable(Database_Ptr db, const _TCHAR* name,
968
968
  convertTable(db, tablenum, func);
969
969
  }
970
970
 
971
+ template <class Database_Ptr>
972
+ void execSql(Database_Ptr db, const char* sql)
973
+ {
974
+ db->execSql(sql);
975
+ #ifdef _UNICODE
976
+ wchar_t buf[1024];
977
+ MultiByteToWideChar(CP_UTF8, 0, sql, -1, buf, 1024);
978
+ validateStatus(db, buf);
979
+ #else
980
+ validateStatus(db, sql);
981
+ #endif
982
+ }
983
+
971
984
  inline void insertTable(dbdef* def, short id, const _TCHAR* name,
972
985
  unsigned short charsetIndex)
973
986
  {
@@ -8,4 +8,5 @@ EXPORTS
8
8
  BTRCALLID32 @5
9
9
  BTRCALL32 @6
10
10
  BeginWinThreadPoolShutdown @7
11
+ RegisterHaNameResolver @8
11
12
 
@@ -469,14 +469,16 @@ short schemaBuilder::execute(database* db, table* mtb, bool nouseNullkey)
469
469
  std::string s = it->path().filename().string();
470
470
  if (isFrmFile(s))
471
471
  {
472
- filename_to_tablename(it->path().stem().string().c_str(), path,
473
- FN_REFLEN);
474
- table* tb = db->openTable(path, TD_OPEN_READONLY, NULL, "");
475
- if (!tb) break;
476
- if (!tb->isView())
472
+ enum legacy_db_type not_used;
473
+ frm_type_enum ftype = dd_frm_type(db->thd(), (char*)it->path().string().c_str(), &not_used);
474
+ if (ftype == FRMTYPE_TABLE)
475
+ {
476
+ filename_to_tablename(it->path().stem().string().c_str(), path,
477
+ FN_REFLEN);
478
+ table* tb = db->openTable(path, TD_OPEN_READONLY, NULL, "");
479
+ if (!tb) break;
477
480
  tables.push_back(tb);
478
- else
479
- db->closeTable(tb);
481
+ }
480
482
  }
481
483
  }
482
484
  }
@@ -889,8 +889,8 @@ public:
889
889
  }
890
890
  }
891
891
  }
892
-
893
- tb->indexInit();
892
+ if (tb->keyNum() >= 0)
893
+ tb->indexInit();
894
894
  tb->blobBuffer()->clear();
895
895
  tb->setBlobFieldCount(blobs);
896
896
  return 0;
@@ -23,6 +23,7 @@
23
23
  #include <bzs/db/engine/mysql/mysqlProtocol.h>
24
24
  #include <bzs/db/engine/mysql/errorMessage.h>
25
25
  #include <bzs/db/engine/mysql/mydebuglog.h>
26
+ #include <bzs/db/engine/mysql/ha.h>
26
27
  #include <bzs/netsvc/server/IAppModule.h> //lookup for result value
27
28
  #include <bzs/db/transactd/appModule.h>
28
29
  #include <bzs/rtl/stl_uty.h>
@@ -36,10 +37,12 @@
36
37
  #include <bzs/rtl/exception.h>
37
38
  #include <random>
38
39
 
39
-
40
40
  extern int getTransactdIsolation();
41
41
  extern unsigned int getTransactdLockWaitTimeout();
42
42
 
43
+ /* implemnts in transactd.cpp */
44
+ extern unsigned int g_tcpServerType;
45
+
43
46
  namespace bzs
44
47
  {
45
48
  namespace db
@@ -404,89 +407,90 @@ bool dbExecuter::connect(request& req)
404
407
  return ret;
405
408
  }
406
409
 
407
- inline bool dbExecuter::doCreateTable(request& req)
410
+ inline void dbExecuter::doCreateTable(request& req)
408
411
  {
409
- // if table name is mata table and database is nothing
410
- // then cretate database too.
411
412
  database* db;
412
- bool ret = getDatabaseWithAuth(req, &db);
413
- if (ret && req.result == 0)
413
+ if (!getDatabaseWithAuth(req, &db) || req.result)
414
414
  {
415
- std::string dbSqlname = getDatabaseName(req, FOR_SQL);
416
- std::string cmd;
417
- if (isMetaDb(req))
418
- { // for database operation
419
- if (((req.keyNum == CR_SUBOP_CREATE_DBONLY) || (req.keyNum == 0)) &&
420
- (db->existsDatabase() == false))
421
- {
422
- req.result = ddl_createDataBase(dbSqlname);
423
- if (req.result == ER_DB_CREATE_EXISTS + MYSQL_ERROR_OFFSET)
424
- req.result = 0;
425
- }
426
- else if (req.keyNum == CR_SUBOP_DROP)
427
- {
428
- if (req.result == 0)
429
- {
430
- std::string dbname = db->name();
431
- dbManager::releaseDatabase(req.cid);
432
- req.result = ddl_dropDataBase(dbname, dbSqlname, req.cid);
433
- if (ER_DB_DROP_EXISTS+ MYSQL_ERROR_OFFSET == req.result) req.result = 0;
434
- }
435
- return ret;
436
- }
415
+ req.result = ERROR_TD_INVALID_CLINETHOST;
416
+ return;
417
+ }
418
+
419
+ // if table name is mata table and database is nothing
420
+ // then cretate database too.
421
+ std::string dbSqlname = getDatabaseName(req, FOR_SQL);
422
+ std::string cmd;
423
+ if (isMetaDb(req))
424
+ { // for database operation
425
+ if (((req.keyNum == CR_SUBOP_CREATE_DBONLY) || (req.keyNum == 0)) &&
426
+ (db->existsDatabase() == false))
427
+ {
428
+ req.result = ddl_createDataBase(dbSqlname);
429
+ if (req.result == ER_DB_CREATE_EXISTS + MYSQL_ERROR_OFFSET)
430
+ req.result = 0;
437
431
  }
438
- if (req.result == 0)
439
- { // table operation
440
- std::string tableSqlName = getTableName(req, FOR_SQL);
441
- std::string tableName = getTableName(req);
442
- if (req.keyNum == CR_SUBOP_DROP) // -128 is delete
432
+ else if (req.keyNum == CR_SUBOP_DROP)
433
+ {
434
+ if (req.result == 0)
443
435
  {
444
- req.result = ddl_dropTable(db, tableName, dbSqlname,
445
- tableSqlName);
446
- if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
447
- req.result = 0;
448
- }
449
- else if (req.keyNum == CR_SUBOP_RENAME)
450
- { // rename new is keybuf
451
- request reqold;
452
- reqold.keybuf = req.data;
453
- reqold.keylen = *req.datalen;
454
- req.result = ddl_renameTable(
455
- db, getTableName(reqold), /*oldname*/
456
- dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
457
- tableSqlName /*newName*/);
436
+ std::string dbname = db->name();
437
+ dbManager::releaseDatabase(req.cid);
438
+ req.result = ddl_dropDataBase(dbname, dbSqlname, req.cid);
439
+ if (ER_DB_DROP_EXISTS+ MYSQL_ERROR_OFFSET == req.result) req.result = 0;
458
440
  }
459
- else if (req.keyNum == CR_SUBOP_SWAPNAME)
460
- { // swap name name2 = keybuf
461
- request reqold;
462
- reqold.keybuf = req.data;
463
- reqold.keylen = *req.datalen;
464
- req.result = ddl_replaceTable(
465
- db, getTableName(reqold), /*oldname*/
466
- tableName, /*newName*/
467
- dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
468
- tableSqlName /*newName*/);
469
- }
470
- else if (req.keyNum != CR_SUBOP_CREATE_DBONLY)
471
- { // create
472
- if (req.data == NULL)
473
- req.result = 1;
474
- else
475
- { //-1 is overwrite
476
- if (req.keyNum == CR_SUB_FLAG_EXISTCHECK && tableName.size())
477
- {
478
- req.result = ddl_dropTable(db, tableName, dbSqlname,
479
- tableSqlName);
480
- if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
481
- req.result = 0;
482
- }
483
- if (req.result == 0)
484
- req.result = ddl_createTable(db, makeSQLcreateTable(req).c_str());
441
+ return;
442
+ }
443
+ }
444
+ if (req.result == 0)
445
+ { // table operation
446
+ std::string tableSqlName = getTableName(req, FOR_SQL);
447
+ std::string tableName = getTableName(req);
448
+ if (req.keyNum == CR_SUBOP_DROP) // -128 is delete
449
+ {
450
+ req.result = ddl_dropTable(db, tableName, dbSqlname,
451
+ tableSqlName);
452
+ if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
453
+ req.result = 0;
454
+ }
455
+ else if (req.keyNum == CR_SUBOP_RENAME)
456
+ { // rename new is keybuf
457
+ request reqold;
458
+ reqold.keybuf = req.data;
459
+ reqold.keylen = *req.datalen;
460
+ req.result = ddl_renameTable(
461
+ db, getTableName(reqold), /*oldname*/
462
+ dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
463
+ tableSqlName /*newName*/);
464
+ }
465
+ else if (req.keyNum == CR_SUBOP_SWAPNAME)
466
+ { // swap name name2 = keybuf
467
+ request reqold;
468
+ reqold.keybuf = req.data;
469
+ reqold.keylen = *req.datalen;
470
+ req.result = ddl_replaceTable(
471
+ db, getTableName(reqold), /*oldname*/
472
+ tableName, /*newName*/
473
+ dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
474
+ tableSqlName /*newName*/);
475
+ }
476
+ else if (req.keyNum != CR_SUBOP_CREATE_DBONLY)
477
+ { // create
478
+ if (req.data == NULL)
479
+ req.result = 1;
480
+ else
481
+ { //-1 is overwrite
482
+ if (req.keyNum == CR_SUB_FLAG_EXISTCHECK && tableName.size())
483
+ {
484
+ req.result = ddl_dropTable(db, tableName, dbSqlname,
485
+ tableSqlName);
486
+ if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
487
+ req.result = 0;
485
488
  }
489
+ if (req.result == 0)
490
+ req.result = ddl_createTable(db, makeSQLcreateTable(req).c_str());
486
491
  }
487
492
  }
488
493
  }
489
- return ret;
490
494
  }
491
495
 
492
496
  // open table and assign handle
@@ -684,16 +688,24 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
684
688
  int ret = 1;
685
689
  m_tb = getTable(req.pbk->handle);
686
690
  char keynum = m_tb->keyNumByMakeOrder(req.keyNum);
687
- if (!m_tb->setKeyNum(keynum))
691
+ if (keynum == -1 && (op == TD_KEY_GE_NEXT_MULTI))
688
692
  {
689
- req.result = m_tb->stat();
690
- return ret;
693
+ m_tb->setNonKey(true);
694
+ op = TD_POS_NEXT_MULTI;
691
695
  }
696
+ else
697
+ {
698
+ if (!m_tb->setKeyNum(keynum))
699
+ {
700
+ req.result = m_tb->stat();
701
+ return ret;
702
+ }
692
703
 
693
- m_tb->setKeyValuesPacked((const uchar*)req.keybuf, req.keylen);
694
- m_tb->seekKey((op == TD_KEY_GE_NEXT_MULTI) ? HA_READ_KEY_OR_NEXT
695
- : HA_READ_KEY_OR_PREV,
696
- m_tb->keymap());
704
+ m_tb->setKeyValuesPacked((const uchar*)req.keybuf, req.keylen);
705
+ m_tb->seekKey((op == TD_KEY_GE_NEXT_MULTI) ? HA_READ_KEY_OR_NEXT
706
+ : HA_READ_KEY_OR_PREV,
707
+ m_tb->keymap());
708
+ }
697
709
 
698
710
  extRequest* ereq = (extRequest*)req.data;
699
711
  bool noBookmark = (ereq->itype & FILTER_CURRENT_TYPE_NOBOOKMARK) != 0;
@@ -713,7 +725,7 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
713
725
  }
714
726
  else
715
727
  req.result = m_readHandler->begin(m_tb, ereq, true, nw,
716
- (op == TD_KEY_GE_NEXT_MULTI),
728
+ (op == TD_KEY_GE_NEXT_MULTI || op == HA_READ_KEY_OR_NEXT),
717
729
  noBookmark);
718
730
  if (req.result != 0)
719
731
  return ret;
@@ -723,6 +735,10 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
723
735
  m_tb->getNextExt(m_readHandler, true, noBookmark);
724
736
  else if (op == TD_KEY_LE_PREV_MULTI)
725
737
  m_tb->getPrevExt(m_readHandler, true, noBookmark);
738
+ else if (op == TD_POS_NEXT_MULTI)
739
+ m_tb->stepNextExt(m_readHandler, false, noBookmark);
740
+ else if (op == TD_POS_PREV_MULTI)
741
+ m_tb->stepPrevExt(m_readHandler, false, noBookmark);
726
742
  }
727
743
  req.result = errorCodeSht(m_tb->stat());
728
744
  if (!m_tb->cursor())
@@ -1411,6 +1427,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1411
1427
  case TD_RECONNECT:
1412
1428
  nw->resize(*req.datalen);
1413
1429
  resultBuffer = nw->ptr();
1430
+
1414
1431
  if (!doOpenTable(req, resultBuffer, true))
1415
1432
  {
1416
1433
  if (req.result == 0)
@@ -1421,8 +1438,12 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1421
1438
  char* p = (char*)req.data;
1422
1439
  req.keyNum = *p;
1423
1440
  if (*(++p) == 0)
1424
- break;
1441
+ {
1442
+ req.paramMask = P_MASK_POSBLK;
1443
+ break; // No bookmark
1444
+ }
1425
1445
  req.data = ((char*)req.data) + 2;
1446
+
1426
1447
  if (m_tb) m_tb->unUse();
1427
1448
  }
1428
1449
  //fall through restore position
@@ -1557,8 +1578,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1557
1578
  req.result = schemaBuilder().execute(getDatabaseCid(req.cid), m_tb, (req.keyNum==1));
1558
1579
  break;
1559
1580
  case TD_CREATETABLE:
1560
- if (!doCreateTable(req))
1561
- req.result = ERROR_TD_INVALID_CLINETHOST;
1581
+ doCreateTable(req);
1562
1582
  break;
1563
1583
  case TD_OPENTABLE:
1564
1584
  nw->resize(*req.datalen);
@@ -1801,6 +1821,11 @@ size_t dbExecuter::getAcceptMessage(char* message, size_t size)
1801
1821
 
1802
1822
  hst->transaction_isolation = (unsigned short)getTransactdIsolation();
1803
1823
  hst->lock_wait_timeout = getTransactdLockWaitTimeout();
1824
+ int role = getRole();
1825
+ if (role == HA_ROLE_MASTER)
1826
+ hst->options |= HST_OPTION_ROLE_MASTER;
1827
+ else if(role == HA_ROLE_SLAVE)
1828
+ hst->options |= HST_OPTION_ROLE_SLAVE;
1804
1829
  if (strcmp(g_auth_type, AUTH_TYPE_MYSQL_STR) == 0)
1805
1830
  {
1806
1831
  makeRandomKey(m_scramble, MYSQL_SCRAMBLE_LENGTH);
@@ -1817,6 +1842,31 @@ size_t dbExecuter::getAcceptMessage(char* message, size_t size)
1817
1842
  // ---------------------------------------------------------------------------
1818
1843
  // class connMgrExecuter
1819
1844
  // ---------------------------------------------------------------------------
1845
+ class safeLockReadChannels
1846
+ {
1847
+ connMgrExecuter* m_exec;
1848
+ bool m_locked;
1849
+ public:
1850
+ safeLockReadChannels(connMgrExecuter* exec) :
1851
+ m_exec(exec), m_locked(false){}
1852
+ bool lock()
1853
+ {
1854
+ int n = 0;
1855
+ while (!haLock())
1856
+ {
1857
+ Sleep(500);
1858
+ if (++n >= 120) return false;
1859
+ }
1860
+ m_locked = true;
1861
+ return m_locked;
1862
+ }
1863
+ int execute(char* buf, size_t& size)
1864
+ {
1865
+ return m_exec->channels(buf, size);
1866
+ }
1867
+ ~safeLockReadChannels() { if (m_locked) haUnlock();}
1868
+ };
1869
+
1820
1870
  connMgrExecuter::connMgrExecuter(request& req, unsigned __int64 parent, blobBuffer* bb)
1821
1871
  : m_req(req), m_modHandle(parent), m_blobBuffer(bb)
1822
1872
  {
@@ -1865,6 +1915,18 @@ int connMgrExecuter::systemVariables(char* buf, size_t& size)
1865
1915
  return serialize(m_req, buf, size, records, st.stat());
1866
1916
  }
1867
1917
 
1918
+ int connMgrExecuter::extendedVariables(netsvc::server::netWriter* nw)
1919
+ {
1920
+ connManager st(m_modHandle);
1921
+ const connection::records& records = st.extendedVariables(m_blobBuffer);
1922
+ int v = serialize(m_req, nw->ptr(), nw->datalen, records, st.stat(), m_blobBuffer);
1923
+ short dymmy = 0;
1924
+ if ((m_req.result == 0) && m_blobBuffer->fieldCount())
1925
+ nw->datalen = m_req.serializeBlobBody(m_blobBuffer, nw->ptr(), nw->datalen,
1926
+ FILE_MAP_SIZE, nw->optionalData(), dymmy);
1927
+ return v;
1928
+ }
1929
+
1868
1930
  int connMgrExecuter::statusVariables(char* buf, size_t& size)
1869
1931
  {
1870
1932
  connManager st(m_modHandle);
@@ -1889,14 +1951,16 @@ int connMgrExecuter::definedTables(char* buf, size_t& size)
1889
1951
  int connMgrExecuter::definedViews(char* buf, size_t& size)
1890
1952
  {
1891
1953
  connManager st(m_modHandle);
1892
- const connection::records& records = st.definedTables((const char*)m_req.keybuf, TABLE_TYPE_VIEW);
1954
+ const connection::records& records =
1955
+ st.definedTables((const char*)m_req.keybuf, TABLE_TYPE_VIEW);
1893
1956
  return serialize(m_req, buf, size, records, st.stat());
1894
1957
  }
1895
1958
 
1896
1959
  int connMgrExecuter::slaveStatus(netsvc::server::netWriter* nw)
1897
1960
  {
1898
1961
  connManager st(m_modHandle);
1899
- const connection::records& records = st.readSlaveStatus(m_blobBuffer);
1962
+ const connection::records& records =
1963
+ st.readSlaveStatus((const char*)m_req.keybuf, m_blobBuffer);
1900
1964
  int v = serialize(m_req, nw->ptr(), nw->datalen, records, st.stat(), m_blobBuffer);
1901
1965
  short dymmy = 0;
1902
1966
  if ((m_req.result == 0) && m_blobBuffer->fieldCount())
@@ -1905,6 +1969,25 @@ int connMgrExecuter::slaveStatus(netsvc::server::netWriter* nw)
1905
1969
  return v;
1906
1970
  }
1907
1971
 
1972
+ int connMgrExecuter::channels(char* buf, size_t& size)
1973
+ {
1974
+ connManager st(m_modHandle);
1975
+ const connection::records& records = st.channels();
1976
+ return serialize(m_req, buf, size, records, st.stat());
1977
+ }
1978
+
1979
+ int connMgrExecuter::slaveHosts(netsvc::server::netWriter* nw)
1980
+ {
1981
+ connManager st(m_modHandle);
1982
+ const connection::records& records = st.slaveHosts(m_blobBuffer);
1983
+ int v = serialize(m_req, nw->ptr(), nw->datalen, records, st.stat(), m_blobBuffer);
1984
+ short dymmy = 0;
1985
+ if ((m_req.result == 0) && m_blobBuffer->fieldCount())
1986
+ nw->datalen = m_req.serializeBlobBody(m_blobBuffer, nw->ptr(), nw->datalen,
1987
+ FILE_MAP_SIZE, nw->optionalData(), dymmy);
1988
+ return v;
1989
+ }
1990
+
1908
1991
  int connMgrExecuter::disconnectOne(char* buf, size_t& size)
1909
1992
  {
1910
1993
  connManager st(m_modHandle);
@@ -1924,44 +2007,158 @@ int connMgrExecuter::disconnectAll(char* buf, size_t& size)
1924
2007
  return EXECUTE_RESULT_SUCCESS;
1925
2008
  }
1926
2009
 
1927
- int connMgrExecuter::commandExec(netsvc::server::netWriter* nw)
2010
+ /* redefined. First defined at transactd.cpp */
2011
+ #define TCP_TPOOL_SERVER 2
2012
+ void haPrintMessage(module* mod, int op, bool retVal)
2013
+ {
2014
+ const char* p="";
2015
+ switch (op)
2016
+ {
2017
+ case TD_STSTCS_HA_LOCK: p = "HA_LOCK"; break;
2018
+ case TD_STSTCS_HA_UNLOCK: p = "HA_UNLOCK"; break;
2019
+ case TD_STSTCS_HA_SET_ROLEMASTER: p = "HA_SET_ROLEMASTER"; break;
2020
+ case TD_STSTCS_HA_SET_ROLENONE: p = "HA_SET_ROLENONE"; break;
2021
+ case TD_STSTCS_HA_SET_ROLESLAVE: p = "HA_SET_ROLESLAVE"; break;
2022
+ case TD_STSTCS_HA_SET_TRXBLOCK: p = "HA_SET_TRXBLOCK"; break;
2023
+ case TD_STSTCS_HA_SET_TRXNOBLOCK: p = "HA_SET_TRXNOBLOCK"; break;
2024
+ case TD_STSTCS_HA_ENABLE_FO: p = "HA_ENABLE_FO"; break;
2025
+ case TD_STSTCS_HA_DISBLE_FO: p = "HA_DISBLE_FO"; break;
2026
+ }
2027
+ if (retVal)
2028
+ sql_print_information("Transactd: %s by %s@%s", p, mod->user(), mod->host());
2029
+ else
2030
+ sql_print_error("Transactd: %s by %s@%s", p, mod->user(), mod->host());
2031
+ }
2032
+
2033
+ void connMgrExecuter::execHaCommand()
1928
2034
  {
1929
- if (m_req.keyNum == TD_STSTCS_DISCONNECT_ONE)
1930
- return disconnectOne(nw->ptr(), nw->datalen);
1931
- if (m_req.keyNum == TD_STSTCS_DISCONNECT_ALL)
1932
- return disconnectAll(nw->ptr(), nw->datalen);
2035
+ if (g_tcpServerType == TCP_TPOOL_SERVER)
2036
+ {
2037
+ m_req.reset();
2038
+ m_req.result = STATUS_NOSUPPORT_OP;
2039
+ return;
2040
+ }
2041
+ bool ret = true;
2042
+ switch ((int)m_req.keyNum)
2043
+ {
2044
+ case TD_STSTCS_HA_LOCK:
2045
+ ret = haLock();
2046
+ break;
2047
+ case TD_STSTCS_HA_UNLOCK:
2048
+ ret = haUnlock();
2049
+ break;
2050
+ case TD_STSTCS_HA_SET_ROLEMASTER:
2051
+ ret = setRole(HA_ROLE_MASTER);
2052
+ break;
2053
+ case TD_STSTCS_HA_SET_ROLENONE:
2054
+ ret = setRole(HA_ROLE_NONE);
2055
+ break;
2056
+ case TD_STSTCS_HA_SET_ROLESLAVE:
2057
+ ret = setRole(HA_ROLE_SLAVE);
2058
+ break;
2059
+ case TD_STSTCS_HA_SET_TRXBLOCK:
2060
+ case TD_STSTCS_HA_SET_TRXNOBLOCK:
2061
+ ret = setTrxBlock(m_req.keyNum == TD_STSTCS_HA_SET_TRXBLOCK);
2062
+ break;
2063
+ case TD_STSTCS_HA_ENABLE_FO:
2064
+ case TD_STSTCS_HA_DISBLE_FO:
2065
+ ret = setEnableFailover(m_req.keyNum == TD_STSTCS_HA_ENABLE_FO);
2066
+ break;
2067
+ }
2068
+ module* mod = dynamic_cast<module*>((module*)m_modHandle);
2069
+ assert(mod);
2070
+ haPrintMessage(mod, m_req.keyNum, ret);
2071
+ m_req.reset();
2072
+ if (ret == false)
2073
+ m_req.result = STATUS_LOCK_ERROR;
2074
+ }
1933
2075
 
1934
- if (*m_req.datalen == (uint_td)63976)
2076
+ int connMgrExecuter::commandExec(netsvc::server::netWriter* nw)
2077
+ {
2078
+ char_td op = m_req.keyNum;
2079
+ try
1935
2080
  {
1936
- switch (m_req.keyNum)
2081
+ if (op == TD_STSTCS_DISCONNECT_ONE)
2082
+ return disconnectOne(nw->ptr(), nw->datalen);
2083
+ else if (op == TD_STSTCS_DISCONNECT_ALL)
2084
+ return disconnectAll(nw->ptr(), nw->datalen);
2085
+ else if (op >= TD_STSTCS_HA_LOCK && op <= TD_STSTCS_HA_DISBLE_FO)
2086
+ execHaCommand();
2087
+ else if (*m_req.datalen == (uint_td)63976)
2088
+ {
2089
+ switch (op)
2090
+ {
2091
+ case TD_STSTCS_READ:
2092
+ return read(nw->ptr(), nw->datalen);
2093
+ case TD_STSTCS_DATABASE_LIST:
2094
+ return definedDatabases(nw->ptr(), nw->datalen);
2095
+ case TD_STSTCS_SYSTEM_VARIABLES:
2096
+ return systemVariables(nw->ptr(), nw->datalen);
2097
+ case TD_STSTCS_STATUS_VARIABLES:
2098
+ return statusVariables(nw->ptr(), nw->datalen);
2099
+ case TD_STSTCS_SCHEMA_TABLE_LIST:
2100
+ return schemaTables(nw->ptr(), nw->datalen);
2101
+ case TD_STSTCS_TABLE_LIST:
2102
+ return definedTables(nw->ptr(), nw->datalen);
2103
+ case TD_STSTCS_VIEW_LIST:
2104
+ return definedViews(nw->ptr(), nw->datalen);
2105
+ case TD_STSTCS_SLAVE_STATUS:
2106
+ return slaveStatus(nw);
2107
+ case TD_STSTCS_SLAVE_HOSTS:
2108
+ return slaveHosts(nw);
2109
+ case TD_STSTCS_SLAVE_CHANNELS:
2110
+ return channels(nw->ptr(), nw->datalen);
2111
+ case TD_STSTCS_SLAVE_CHANNELS_LOCK:
2112
+ {
2113
+ safeLockReadChannels readChannels(this);
2114
+ if (readChannels.lock())
2115
+ return readChannels.execute(nw->ptr(), nw->datalen);
2116
+ m_req.reset();
2117
+ m_req.result = STATUS_LOCK_ERROR;
2118
+ break;
2119
+ }
2120
+ case TD_STSTCS_EXTENDED_VARIABLES:
2121
+ return extendedVariables(nw);
2122
+ default:
2123
+ m_req.reset();
2124
+ m_req.result = STATUS_NOSUPPORT_OP;
2125
+ break;
2126
+ }
2127
+ }else
1937
2128
  {
1938
- case TD_STSTCS_READ:
1939
- return read(nw->ptr(), nw->datalen);
1940
- case TD_STSTCS_DATABASE_LIST:
1941
- return definedDatabases(nw->ptr(), nw->datalen);
1942
- case TD_STSTCS_SYSTEM_VARIABLES:
1943
- return systemVariables(nw->ptr(), nw->datalen);
1944
- case TD_STSTCS_STATUS_VARIABLES:
1945
- return statusVariables(nw->ptr(), nw->datalen);
1946
- case TD_STSTCS_SCHEMA_TABLE_LIST:
1947
- return schemaTables(nw->ptr(), nw->datalen);
1948
- case TD_STSTCS_TABLE_LIST:
1949
- return definedTables(nw->ptr(), nw->datalen);
1950
- case TD_STSTCS_VIEW_LIST:
1951
- return definedViews(nw->ptr(), nw->datalen);
1952
- case TD_STSTCS_SLAVE_STATUS:
1953
- return slaveStatus(nw);
1954
- default:
1955
2129
  m_req.reset();
1956
- m_req.result = STATUS_NOSUPPORT_OP;
1957
- break;
2130
+ m_req.result = SERVER_CLIENT_NOT_COMPATIBLE;
1958
2131
  }
1959
- }else
2132
+ nw->datalen = m_req.serialize(NULL, nw->ptr());
2133
+ }
2134
+ catch (bzs::rtl::exception& e)
1960
2135
  {
1961
- m_req.reset();
1962
- m_req.result = SERVER_CLIENT_NOT_COMPATIBLE;
2136
+ std::string s = *getMsg(e);
2137
+ const int* code = getCode(e);
2138
+ if (code)
2139
+ m_req.result = *code;
2140
+ else
2141
+ {
2142
+ m_req.result = 20000;
2143
+ s = boost::diagnostic_information(e);
2144
+ }
2145
+ char buf[256];
2146
+ sprintf_s(buf, 256, "Stastics operation %d : ", (int)op);
2147
+ s.insert(0, buf);
2148
+ printWarningMessage(code, &s);
2149
+ }
2150
+ catch (...)
2151
+ {
2152
+ try
2153
+ {
2154
+ DEBUG_ERROR_MEMDUMP(20001, "error", m_req.m_readBuffer,
2155
+ *((unsigned int*)m_req.m_readBuffer))
2156
+ m_req.reset();
2157
+ m_req.result = 20001;
2158
+ dumpStdErr(op, m_req, NULL);
2159
+ }
2160
+ catch(...){}
1963
2161
  }
1964
- nw->datalen = m_req.serialize(NULL, nw->ptr());
1965
2162
  return EXECUTE_RESULT_SUCCESS;
1966
2163
  }
1967
2164
 
@@ -1978,6 +2175,20 @@ commandExecuter::~commandExecuter()
1978
2175
  m_dbExec.reset();
1979
2176
  }
1980
2177
 
2178
+ int commandExecuter::execute(netsvc::server::netWriter* nw)
2179
+ {
2180
+ if (m_req.op == TD_STASTISTICS)
2181
+ return connMgrExecuter(m_req, (unsigned __int64)m_dbExec->mod(),
2182
+ m_dbExec->m_blobBuffer).commandExec(nw);
2183
+ int ret = m_dbExec->commandExec(m_req, nw);
2184
+
2185
+ // Start blocking mode need lock slave servers first.
2186
+ // therefore
2187
+ if (isTrxBlocking() && m_dbExec->trxProcessing() == 0)
2188
+ return EXECUTE_RESULT_SEND_QUIT;
2189
+ return ret;
2190
+ }
2191
+
1981
2192
  size_t commandExecuter::perseRequestEnd(const char* p, size_t transfered,
1982
2193
  bool& comp) const
1983
2194
  {