transactd 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/bin/common/tdclc_32_2_2.dll +0 -0
  3. data/bin/common/tdclc_64_2_2.dll +0 -0
  4. data/build/swig/ruby/generate.cmd +45 -0
  5. data/build/swig/ruby/generate.sh +40 -0
  6. data/build/swig/ruby/tdclrb_wrap.cpp +406 -969
  7. data/build/swig/tdcl.i +88 -0
  8. data/build/tdclc/CMakeLists.txt +5 -1
  9. data/build/tdclc/tdclc.cbproj +1 -1
  10. data/build/tdclc/tdclc.rc +4 -4
  11. data/build/tdclcpp/tdclcpp.rc +4 -4
  12. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  13. data/build/tdclrb/tdclrb.rc +4 -4
  14. data/source/bzs/db/engine/mysql/database.cpp +165 -74
  15. data/source/bzs/db/engine/mysql/database.h +19 -5
  16. data/source/bzs/db/engine/mysql/dbManager.cpp +33 -11
  17. data/source/bzs/db/engine/mysql/dbManager.h +6 -1
  18. data/source/bzs/db/engine/mysql/mydebuglog.h +12 -0
  19. data/source/bzs/db/engine/mysql/mysqlInternal.h +10 -3
  20. data/source/bzs/db/engine/mysql/mysqlThd.cpp +20 -8
  21. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +12 -7
  22. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +1 -1
  23. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +1 -0
  24. data/source/bzs/db/protocol/tdap/client/client.cpp +17 -15
  25. data/source/bzs/db/protocol/tdap/client/client.h +102 -30
  26. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +1 -1
  27. data/source/bzs/db/protocol/tdap/client/database.cpp +32 -10
  28. data/source/bzs/db/protocol/tdap/client/database.h +1 -0
  29. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +0 -2
  30. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +2 -0
  31. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +47 -42
  32. data/source/bzs/db/protocol/tdap/client/fields.h +3 -1
  33. data/source/bzs/db/protocol/tdap/client/filter.h +3 -3
  34. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +18 -2
  35. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +3 -2
  36. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +14 -6
  37. data/source/bzs/db/protocol/tdap/client/nsTable.h +12 -12
  38. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +6 -3
  39. data/source/bzs/db/protocol/tdap/client/request.h +1 -0
  40. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +101 -64
  41. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +3 -0
  42. data/source/bzs/db/protocol/tdap/client/stringConverter.h +9 -13
  43. data/source/bzs/db/protocol/tdap/client/table.cpp +73 -56
  44. data/source/bzs/db/protocol/tdap/client/table.h +8 -8
  45. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +52 -100
  46. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +8 -1
  47. data/source/bzs/db/protocol/tdap/mysql/request.h +6 -0
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +349 -189
  49. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +28 -12
  50. data/source/bzs/db/protocol/tdap/tdapRequest.h +5 -4
  51. data/source/bzs/db/protocol/tdap/tdapSchema.h +6 -1
  52. data/source/bzs/db/protocol/tdap/tdapcapi.h +29 -4
  53. data/source/bzs/db/protocol/tdap/uri.h +297 -0
  54. data/source/bzs/db/transactd/appModule.cpp +41 -16
  55. data/source/bzs/db/transactd/appModule.h +1 -2
  56. data/source/bzs/db/transactd/transactd.cpp +37 -14
  57. data/source/bzs/env/crosscompile.h +1 -3
  58. data/source/bzs/example/queryData.cpp +2 -2
  59. data/source/bzs/netsvc/client/iconnection.h +3 -1
  60. data/source/bzs/netsvc/client/tcpClient.cpp +75 -28
  61. data/source/bzs/netsvc/client/tcpClient.h +94 -62
  62. data/source/bzs/netsvc/server/IAppModule.h +2 -2
  63. data/source/bzs/netsvc/server/serverCpt.cpp +17 -10
  64. data/source/bzs/netsvc/server/serverPipe.cpp +26 -19
  65. data/source/bzs/netsvc/server/serverTpool.cpp +8 -2
  66. data/source/bzs/rtl/debuglog.cpp +21 -5
  67. data/source/bzs/rtl/debuglog.h +1 -1
  68. data/source/bzs/test/tdclphp/transactd_Test.php +183 -37
  69. data/source/bzs/test/tdclphp/transactd_pool_Test.php +1 -2
  70. data/source/bzs/test/tdclrb/transactd_spec.rb +183 -39
  71. data/source/bzs/test/transactdBench/scaling_bench.cpp +3 -3
  72. data/source/bzs/test/trdclengn/test_trdclengn.cpp +172 -57
  73. data/source/global/boost/sha1.hpp +223 -0
  74. data/source/global/tdclatl/ConnectParams.cpp +2 -2
  75. data/source/global/tdclatl/ConnectParams.h +1 -1
  76. data/source/global/tdclatl/Database.cpp +18 -0
  77. data/source/global/tdclatl/Database.h +5 -0
  78. data/source/global/tdclatl/tdclatl.idl +23 -1
  79. data/source/linux/linuxTypes.h +2 -0
  80. metadata +8 -6
  81. data/bin/common/tdclc_32_2_1.dll +0 -0
  82. data/bin/common/tdclc_64_2_1.dll +0 -0
  83. data/source/bzs/db/protocol/tdap/client/memRecordset.cpp +0 -448
  84. data/source/bzs/db/protocol/tdap/client/memRecordset.h +0 -159
@@ -34,6 +34,11 @@
34
34
  #include "databaseSchema.h"
35
35
  #include <bzs/db/transactd/connManager.h>
36
36
  #include <bzs/rtl/exception.h>
37
+ #include <random>
38
+
39
+
40
+ extern unsigned int getTransactdIsolation();
41
+ extern unsigned int getTransactdLockWaitTimeout();
37
42
 
38
43
  namespace bzs
39
44
  {
@@ -205,11 +210,12 @@ void dumpStdErr(int op, request& req, table* tb)
205
210
  //-------------------------------------------------------------
206
211
  // class dbExecuter
207
212
  //-------------------------------------------------------------
208
-
209
- dbExecuter::dbExecuter()
213
+ #define MYSQL_ERROR_OFFSET 25000
214
+ dbExecuter::dbExecuter(netsvc::server::IAppModule* mod)
210
215
  : dbManager(), m_readHandler(new ReadRecordsHandler()),
211
- m_blobBuffer(new blobBuffer())
216
+ m_blobBuffer(new blobBuffer()), m_mod(mod)
212
217
  {
218
+ m_scramble[0] = 0x00;
213
219
  }
214
220
 
215
221
  dbExecuter::~dbExecuter()
@@ -218,25 +224,6 @@ dbExecuter::~dbExecuter()
218
224
  delete m_readHandler;
219
225
  }
220
226
 
221
- void dbExecuter::connect(request& req)
222
- {
223
- req.paramMask = 0;
224
- if (req.keyNum == LG_SUBOP_DISCONNECT)
225
- dbManager::releaseDatabase(req.cid);
226
- else
227
- {
228
- std::string dbname = getDatabaseName(req);
229
- std::string dbSqlname = getDatabaseName(req, FOR_SQL);
230
- // exec SQL use database
231
- if (dbname != "")
232
- {
233
- database* db = getDatabase(dbname.c_str(), req.cid);
234
- dbSqlname.insert(0, "use ");
235
- req.result = ddl_execSql(db->thd(), dbSqlname);
236
- }
237
- }
238
- }
239
-
240
227
  void dbExecuter::releaseDatabase(request& req, int op)
241
228
  {
242
229
  req.paramMask = 0;
@@ -249,11 +236,10 @@ void dbExecuter::releaseDatabase(request& req, int op)
249
236
  std::string dbExecuter::makeSQLcreateTable(const request& req)
250
237
  {
251
238
  return (const char*)req.data;
252
- // return sql;
253
239
  }
254
240
 
255
241
  int dbExecuter::errorCode(int ha_error)
256
- { // see mysqld_error.h or my_base.h or dbManager.h
242
+ { // see mysqld_error.h or my_base.h or dbManager.h share/errmsg.txt
257
243
 
258
244
  if (ha_error < HA_ERR_FIRST)
259
245
  return ha_error;
@@ -281,12 +267,13 @@ int dbExecuter::errorCode(int ha_error)
281
267
  return STATUS_TABLE_EXISTS_ERROR;
282
268
  else if (ha_error == DBM_ERROR_TABLE_USED)
283
269
  return STATUS_CANNOT_LOCK_TABLE;
284
- return 25000 + ha_error;
270
+ else if(ha_error == ER_BAD_DB_ERROR)
271
+ return ERROR_NO_DATABASE;
272
+ return MYSQL_ERROR_OFFSET + ha_error;
285
273
  }
286
274
 
287
275
  bool isMetaDb(const request& req)
288
276
  {
289
-
290
277
  char buf[MAX_PATH];
291
278
  strncpy(buf, (char*)req.keybuf, MAX_PATH);
292
279
  _strlwr(buf);
@@ -296,31 +283,136 @@ bool isMetaDb(const request& req)
296
283
  return (st != NULL);
297
284
  }
298
285
 
299
- inline void dbExecuter::doCreateTable(request& req)
286
+ inline bool getUserPasswd(request& req, char* &user, char* &pwd)
300
287
  {
301
- // if table name is mata table and database is nothing
302
- // then cretate database too.
303
- std::string dbname = getDatabaseName(req);
304
- std::string dbSqlname = getDatabaseName(req, FOR_SQL);
288
+ char* p = strchr((char*)req.keybuf, '\t');
289
+ if (p)
290
+ {
291
+ p = strchr(++p, '\t');
292
+ if (p)
293
+ {
294
+ pwd = ++p;
295
+ user = pwd + MYSQL_SCRAMBLE_LENGTH;
296
+ while (p < user)
297
+ if (*p++) return true;
298
+ }
299
+ return false;
300
+ }
301
+ return false;
302
+ }
303
+
304
+ inline bool dbExecuter::doAuthentication(request& req, database* db)
305
+ {
306
+ if (m_authChecked) return true;
307
+ bool ret = true;
308
+ if (strcmp(g_auth_type, AUTH_TYPE_MYSQL_STR)==0)
309
+ {
310
+ ret = false;
311
+ char host[MAX_HOSTNAME];
312
+ char *user = 0x00;
313
+ char *pwd = 0x00;
314
+ bool pwdRecieved = getUserPasswd(req, user, pwd);
315
+ if (user && user[0] && m_mod->checkHost(user, host, MAX_HOSTNAME))
316
+ {
317
+ //uint8* p = find_acl_user_(host, user, FALSE);
318
+ unsigned char buf[22];
319
+ unsigned char* p = db->getUserSha1Passwd(host, user, buf);
320
+ if (!pwdRecieved && !p)
321
+ ret = true;
322
+ else if (p && pwdRecieved)
323
+ ret = (FALSE == check_scramble((const unsigned char*)pwd, (const char*)m_scramble, p));
324
+ if (ret)
325
+ {
326
+ m_user = user;
327
+ m_host = host;
328
+ }
329
+ }
330
+ }
331
+ m_authChecked = ret;
332
+ return ret;
333
+ }
334
+
335
+ /*
336
+ @param connect Is connect command, The database name is not required
337
+ @return 0 auth failed
338
+ 1 success but see req.result
339
+ */
340
+ bool dbExecuter::getDatabaseWithAuth(request& req, database** db, bool connect)
341
+ {
342
+ *db = NULL;
343
+ bool created = false;
344
+ std::string dbname = getDatabaseName(req);
345
+ bool ret = false;
346
+ if (connect && dbname == "")
347
+ dbname = "mysql";
348
+ else
349
+ connect = false;
305
350
  if (dbname != "")
306
351
  {
307
- std::string cmd;
308
- database* db = getDatabase(dbname.c_str(), req.cid);
352
+ *db = getDatabase(dbname.c_str(), req.cid, created);
353
+ if (*db)
354
+ ret = doAuthentication(req, *db);
355
+ if (connect || (created && !ret))
356
+ {
357
+ dbManager::releaseDatabase(req.cid);
358
+ *db = NULL;
359
+ }
360
+ }else
361
+ req.result = 1;
362
+
363
+ return ret;
364
+ }
365
+
366
+ /* When connect failed, Delete database object.
367
+
368
+ */
369
+ bool dbExecuter::connect(request& req)
370
+ {
371
+ req.paramMask = 0;
372
+ if (req.keyNum == LG_SUBOP_DISCONNECT)
373
+ {
374
+ dbManager::releaseDatabase(req.cid);
375
+ return true;
376
+ }
377
+ database* db = NULL;
378
+ bool ret = getDatabaseWithAuth(req, &db, true);
379
+ if (ret && (req.result == 0) && db)
380
+ {
381
+ std::string dbSqlname = getDatabaseName(req, FOR_SQL);
382
+ dbSqlname.insert(0, "use ");
383
+ req.result = ddl_execSql(db->thd(), dbSqlname);
384
+ }
385
+ if (db && (!ret || req.result))
386
+ dbManager::releaseDatabase(req.cid);
387
+ return ret;
388
+ }
309
389
 
390
+ inline bool dbExecuter::doCreateTable(request& req)
391
+ {
392
+ // if table name is mata table and database is nothing
393
+ // then cretate database too.
394
+ database* db;
395
+ bool ret = getDatabaseWithAuth(req, &db);
396
+ if (ret && req.result == 0)
397
+ {
398
+ std::string dbSqlname = getDatabaseName(req, FOR_SQL);
399
+ std::string cmd;
310
400
  if (isMetaDb(req))
311
401
  { // for database operation
312
402
  if ((req.keyNum == 0) && (db->existsDatabase() == false))
403
+ {
313
404
  req.result = ddl_createDataBase(db->thd(), dbSqlname);
405
+ if (req.result == ER_DB_CREATE_EXISTS + MYSQL_ERROR_OFFSET)
406
+ req.result = 0;
407
+ }
314
408
  else if (req.keyNum == CR_SUBOP_DROP)
315
409
  {
316
- std::string tableName = getTableName(req);
317
- if (db->existsTable(tableName))
318
- req.result = ddl_dropTable(db, tableName, dbSqlname,
319
- getTableName(req, FOR_SQL));
320
410
  if (req.result == 0)
321
- req.result = ddl_dropDataBase(db->thd(), dbname, dbSqlname);
322
- req.result = errorCodeSht(req.result);
323
- return;
411
+ {
412
+ req.result = ddl_dropDataBase(db->thd(), db->name(), dbSqlname);
413
+ if (ER_DB_DROP_EXISTS+ MYSQL_ERROR_OFFSET == req.result) req.result = 0;
414
+ }
415
+ return ret;
324
416
  }
325
417
  }
326
418
  if (req.result == 0)
@@ -331,10 +423,10 @@ inline void dbExecuter::doCreateTable(request& req)
331
423
  std::string tableName = getTableName(req);
332
424
  if (req.keyNum == CR_SUBOP_DROP) // -128 is delete
333
425
  {
334
-
335
- if (db->existsTable(tableName))
336
- req.result = ddl_dropTable(db, tableName, dbSqlname,
337
- tableSqlName);
426
+ req.result = ddl_dropTable(db, tableName, dbSqlname,
427
+ tableSqlName);
428
+ if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
429
+ req.result = 0;
338
430
  }
339
431
  else if (req.keyNum == CR_SUBOP_RENAME)
340
432
  { // rename new is keybuf
@@ -342,10 +434,8 @@ inline void dbExecuter::doCreateTable(request& req)
342
434
  reqold.keybuf = req.data;
343
435
  reqold.keylen = *req.datalen;
344
436
  req.result = ddl_renameTable(
345
- db, getTableName(reqold) /*oldname*/
346
- ,
347
- dbSqlname, getTableName(reqold, FOR_SQL) /*oldname*/
348
- ,
437
+ db, getTableName(reqold), /*oldname*/
438
+ dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
349
439
  tableSqlName /*newName*/);
350
440
  }
351
441
  else if (req.keyNum == CR_SUBOP_SWAPNAME)
@@ -354,12 +444,9 @@ inline void dbExecuter::doCreateTable(request& req)
354
444
  reqold.keybuf = req.data;
355
445
  reqold.keylen = *req.datalen;
356
446
  req.result = ddl_replaceTable(
357
- db, getTableName(reqold) /*oldname*/
358
- ,
359
- tableName /*newName*/
360
- ,
361
- dbSqlname, getTableName(reqold, FOR_SQL) /*oldname*/
362
- ,
447
+ db, getTableName(reqold), /*oldname*/
448
+ tableName, /*newName*/
449
+ dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
363
450
  tableSqlName /*newName*/);
364
451
  }
365
452
  else
@@ -368,10 +455,13 @@ inline void dbExecuter::doCreateTable(request& req)
368
455
  req.result = 1;
369
456
  else
370
457
  { //-1 is overwrite
371
- if ((req.keyNum == CR_SUB_FLAG_EXISTCHECK) &&
372
- (db->existsTable(tableName)))
458
+ if (req.keyNum == CR_SUB_FLAG_EXISTCHECK)
459
+ {
373
460
  req.result = ddl_dropTable(db, tableName, dbSqlname,
374
461
  tableSqlName);
462
+ if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
463
+ req.result = 0;
464
+ }
375
465
  if (req.result == 0)
376
466
  req.result =
377
467
  ddl_execSql(db->thd(), makeSQLcreateTable(req));
@@ -380,51 +470,51 @@ inline void dbExecuter::doCreateTable(request& req)
380
470
  }
381
471
  }
382
472
  }
383
- else
384
- req.result = 1;
385
- req.result = errorCodeSht(req.result);
473
+ return ret;
386
474
  }
387
475
 
476
+
388
477
  // open table and assign handle
389
- inline void dbExecuter::doOpenTable(request& req)
478
+ inline bool dbExecuter::doOpenTable(request& req)
390
479
  {
391
- std::string dbname = getDatabaseName(req);
392
- if (dbname != "")
480
+ database* db;
481
+ bool ret = getDatabaseWithAuth(req, &db);
482
+ if (ret && req.result == 0)
393
483
  {
394
- database* db;
484
+ table* tb = NULL;
395
485
  {// Lock open table by another thread
396
486
  boost::mutex::scoped_lock lck(g_mutex_opentable);
397
487
  if (req.keyNum == TD_OPEN_EXCLUSIVE/* && isMetaDb(req)*/)
398
488
  {
399
- if (database::tableRef.count(dbname, getTableName(req)))
400
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_CANNOT_LOCK_TABLE,
401
- "lockTable error.");
489
+ if (database::tableRef.count(db->name(), getTableName(req)))
490
+ {
491
+ req.result = STATUS_CANNOT_LOCK_TABLE;
492
+ return ret;
493
+ }
402
494
  }
403
- db = getDatabase(dbname.c_str(), req.cid);
404
- m_tb = db->openTable(
405
- getTableName(req), req.keyNum,
406
- getOwnerName(req)); // if error occured that throw exception
495
+ // if error occured that throw no exception
496
+ tb = db->openTable(getTableName(req), req.keyNum, getOwnerName(req));
407
497
  req.result = db->stat();
408
498
  }
409
499
 
410
- if (m_tb)
500
+ if (tb)
411
501
  {
502
+ tb->setBlobBuffer(m_blobBuffer);
412
503
  try
413
504
  {
414
- req.pbk->handle = addHandle(getDatabaseID(req.cid), m_tb->id());
415
- m_tb = getTable(req.pbk->handle);
416
- m_tb->setBlobBuffer(m_blobBuffer);
505
+ uint hdl = addHandle(getDatabaseID(req.cid), tb->id());
506
+ m_tb = getTable(hdl);
507
+ req.pbk->handle = hdl;
417
508
  req.paramMask = P_MASK_POSBLK;
418
509
  }
419
510
  catch (bzs::rtl::exception& e)
420
511
  {
421
- m_tb->close();
512
+ tb->close();
422
513
  throw e;
423
514
  }
424
515
  }
425
516
  }
426
- else
427
- req.result = 1;
517
+ return ret;
428
518
  }
429
519
 
430
520
  inline void readAfter(request& req, table* tb, dbExecuter* dbm)
@@ -767,7 +857,6 @@ inline void dbExecuter::doInsert(request& req)
767
857
  m_tb->clearBuffer();
768
858
  m_tb->setRecordFromPacked((const uchar*)req.data, *(req.datalen),
769
859
  req.blobHeader);
770
- smartBulkInsert sbi(m_tb, 1);
771
860
  __int64 aincValue = m_tb->insert(ncc);
772
861
  req.result = errorCodeSht(m_tb->stat());
773
862
  if (aincValue)
@@ -894,6 +983,11 @@ inline void dbExecuter::doInsertBulk(request& req)
894
983
  req.result = errorCodeSht(m_tb->stat());
895
984
  }
896
985
 
986
+ /**
987
+ @result
988
+ 2byte recordLength
989
+ 4byte esitimate recordCount
990
+ */
897
991
  inline void dbExecuter::doStat(request& req)
898
992
  {
899
993
  m_tb = getTable(req.pbk->handle);
@@ -938,10 +1032,10 @@ inline short getTrnsactionType(int op)
938
1032
 
939
1033
  inline rowLockMode* getRowLockMode(int op, rowLockMode* lck)
940
1034
  {
941
- lck->lock = false;
1035
+ lck->lock = false;
942
1036
  lck->read = (op > ROW_LOCK_S);
943
1037
  if (op > 1000)
944
- op = op % 1000;
1038
+ op = op % 1000;
945
1039
  if (op < NOWAIT_WRITE)
946
1040
  {
947
1041
  if (op >= LOCK_SINGLE_NOWAIT && op < LOCK_MULTI_NOWAIT)
@@ -974,54 +1068,14 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
974
1068
  if (pbk == NULL)
975
1069
  pbk = &tmp;
976
1070
  req.reset();
977
- switch (op)
978
- {
979
- case TD_GETSERVER_CHARSET:
1071
+ if (!m_authChecked)
980
1072
  {
981
- if (*req.datalen == sizeof(trdVersiton))
982
- {
983
- trdVersiton* ver = (trdVersiton*)req.data;
984
- strcpy_s(ver->cherserServer, sizeof(ver->cherserServer),
985
- global_system_variables.collation_server->csname);
986
- ver->srvMajor = TRANSACTD_VER_MAJOR;
987
- ver->srvMinor = TRANSACTD_VER_MINOR;
988
- ver->srvRelease = TRANSACTD_VER_RELEASE;
989
- req.resultLen = sizeof(trdVersiton);
990
- // req.data = (void*)
991
- // global_system_variables.collation_server->csname;
992
- // req.resultLen = (uint_td)strlen(
993
- // global_system_variables.collation_server->csname);
994
- req.paramMask |= P_MASK_DATA | P_MASK_DATALEN;
995
- }
996
- else
997
- req.result = SERVER_CLIENT_NOT_COMPATIBLE;
998
- break;
1073
+ if (op != TD_CONNECT && op != TD_CREATETABLE &&
1074
+ op != TD_OPENTABLE && op != TD_GETSERVER_CHARSET)
1075
+ return EXECUTE_RESULT_ACCESS_DNIED;
999
1076
  }
1000
- case TD_CONNECT:
1001
- connect(req);
1002
- break;
1003
- case TD_RESET_CLIENT:
1004
- case TD_STOP_ENGINE: // close all table
1005
- releaseDatabase(req, op);
1006
- break;
1007
- case TD_AUTOMEKE_SCHEMA:
1008
- m_tb = getTable(req.pbk->handle, SQLCOM_INSERT);
1009
- req.result = schemaBuilder().execute(getDatabaseCid(req.cid), m_tb);
1010
- break;
1011
- case TD_CREATETABLE:
1012
- doCreateTable(req);
1013
- break;
1014
- case TD_OPENTABLE:
1015
- doOpenTable(req);
1016
- break;
1017
- case TD_CLOSETABLE:
1018
- m_tb = getTable(req.pbk->handle);
1019
- if (m_tb)
1020
- {
1021
- m_tb->close();
1022
- m_tb = NULL;
1023
- }
1024
- break;
1077
+ switch (op)
1078
+ {
1025
1079
  case TD_KEY_SEEK:
1026
1080
  case TD_KEY_AFTER:
1027
1081
  case TD_KEY_OR_AFTER:
@@ -1109,64 +1163,6 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1109
1163
  readAfter(req, m_tb, this);
1110
1164
  break;
1111
1165
  }
1112
- case TD_GETDIRECTORY:
1113
- {
1114
- database* db = getDatabaseCid(req.cid);
1115
- if (db->name().size() < 64)
1116
- {
1117
- req.keylen = (uchar_td)db->name().size() + 1;
1118
- req.keybuf = (void*)db->name().c_str();
1119
- req.paramMask = P_MASK_KEYBUF;
1120
- }
1121
- else
1122
- req.result = STATUS_BUFFERTOOSMALL;
1123
- break;
1124
- }
1125
- case TD_VERSION:
1126
- if (*req.datalen >= sizeof(version) * 3)
1127
- {
1128
- version* v = (version*)req.data;
1129
- ++v;
1130
- v->majorVersion = MYSQL_VERSION_ID / 10000;
1131
- v->minorVersion = (MYSQL_VERSION_ID / 100) % 100;
1132
- v->Type = 'M';
1133
- ++v;
1134
- v->majorVersion = TRANSACTD_VER_MAJOR;
1135
- v->minorVersion = TRANSACTD_VER_MINOR;
1136
- v->Type = 'T';
1137
- req.paramMask = P_MASK_DATA | P_MASK_DATALEN;
1138
- req.resultLen = sizeof(version) * 3;
1139
- }
1140
- else
1141
- req.result = STATUS_BUFFERTOOSMALL;
1142
- break;
1143
- case TD_CLEAR_OWNERNAME:
1144
- req.keybuf = (void_td*)"";
1145
- case TD_SET_OWNERNAME:
1146
- {
1147
- database* db = getDatabaseCid(req.cid);
1148
- m_tb = getTable(req.pbk->handle);
1149
- int num = (req.keyNum > 1) ? req.keyNum - 2 : req.keyNum;
1150
- num += '0';
1151
- std::string s("%@%");
1152
- s += (const char*)&num;
1153
- s += (const char*)req.keybuf;
1154
- req.result = ddl_execSql(
1155
- db->thd(),
1156
- makeSQLChangeTableComment(db->name(), m_tb->name(), s.c_str()));
1157
- break;
1158
- }
1159
- case TD_DROP_INDEX:
1160
- { // Key name of multi byte charctord is not supported. Use only ascii.
1161
- database* db = getDatabaseCid(req.cid);
1162
- m_tb = getTable(req.pbk->handle);
1163
- req.result = ddl_execSql(
1164
- db->thd(),
1165
- makeSQLDropIndex(
1166
- db->name(), m_tb->name(),
1167
- m_tb->keyName(m_tb->keyNumByMakeOrder(req.keyNum))));
1168
- break;
1169
- }
1170
1166
  case TD_KEY_GE_NEXT_MULTI:
1171
1167
  case TD_KEY_LE_PREV_MULTI:
1172
1168
  nw->setClientBuffferSize(*(req.datalen));
@@ -1237,10 +1233,128 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1237
1233
  m_tb = getTable(req.pbk->handle);
1238
1234
  req.result = m_tb->unlock() ? STATUS_NO_CURRENT : 0;
1239
1235
  break;
1236
+ /* ddl or once at connection
1237
+ */
1238
+ case TD_GETSERVER_CHARSET:
1239
+ {
1240
+ if (*req.datalen == sizeof(trdVersiton))
1241
+ {
1242
+ trdVersiton* ver = (trdVersiton*)req.data;
1243
+ strcpy_s(ver->cherserServer, sizeof(ver->cherserServer),
1244
+ global_system_variables.collation_server->csname);
1245
+ ver->srvMajor = TRANSACTD_VER_MAJOR;
1246
+ ver->srvMinor = TRANSACTD_VER_MINOR;
1247
+ ver->srvRelease = TRANSACTD_VER_RELEASE;
1248
+ req.resultLen = sizeof(trdVersiton);
1249
+ req.paramMask |= P_MASK_DATA | P_MASK_DATALEN;
1250
+ }
1251
+ else
1252
+ req.result = SERVER_CLIENT_NOT_COMPATIBLE;
1253
+ break;
1254
+ }
1255
+ case TD_CONNECT:
1256
+ if (!connect(req))
1257
+ req.result = ERROR_TD_INVALID_CLINETHOST;
1258
+ break;
1259
+ case TD_RESET_CLIENT:
1260
+ case TD_STOP_ENGINE: // close all table
1261
+ releaseDatabase(req, op);
1262
+ break;
1263
+ case TD_AUTOMEKE_SCHEMA:
1264
+ m_tb = getTable(req.pbk->handle, SQLCOM_INSERT);
1265
+ req.result = schemaBuilder().execute(getDatabaseCid(req.cid), m_tb);
1266
+ break;
1267
+ case TD_CREATETABLE:
1268
+ if (!doCreateTable(req))
1269
+ req.result = ERROR_TD_INVALID_CLINETHOST;
1270
+ break;
1271
+ case TD_OPENTABLE:
1272
+ if (!doOpenTable(req))
1273
+ req.result = ERROR_TD_INVALID_CLINETHOST;
1274
+ break;
1275
+ case TD_CLOSETABLE:
1276
+ m_tb = getTable(req.pbk->handle);
1277
+ if (m_tb)
1278
+ {
1279
+ m_tb->close();
1280
+ m_tb = NULL;
1281
+ }
1282
+ break;
1283
+ case TD_BUILD_INDEX:
1284
+ {
1285
+ database* db = getDatabaseCid(req.cid);
1286
+ m_tb = getTable(req.pbk->handle);
1287
+ std::string cmd((const char*)req.data);
1288
+ std::string tbname = m_tb->name();
1289
+ req.result = ddl_addIndex(db, tbname, cmd);
1290
+ break;
1291
+ }
1292
+ case TD_DROP_INDEX:
1293
+ { // Key name of multi byte charctor is not supported. Use only ascii.
1294
+ database* db = getDatabaseCid(req.cid);
1295
+ m_tb = getTable(req.pbk->handle);
1296
+ req.result = ddl_execSql(db->thd(),
1297
+ makeSQLDropIndex(db->name(), m_tb->name(),
1298
+ m_tb->keyName(m_tb->keyNumByMakeOrder(req.keyNum))));
1299
+ break;
1300
+ }
1301
+ case TD_GETDIRECTORY:
1302
+ {
1303
+ database* db = getDatabaseCid(req.cid);
1304
+ if (db->name().size() < 64)
1305
+ {
1306
+ req.keylen = (uchar_td)db->name().size() + 1;
1307
+ req.keybuf = (void*)db->name().c_str();
1308
+ req.paramMask = P_MASK_KEYBUF;
1309
+ }
1310
+ else
1311
+ req.result = STATUS_BUFFERTOOSMALL;
1312
+ break;
1313
+ }
1314
+ case TD_VERSION:
1315
+ if (*req.datalen >= sizeof(version) * 3)
1316
+ {
1317
+ version* v = (version*)req.data;
1318
+ ++v;
1319
+ v->majorVersion = MYSQL_VERSION_ID / 10000;
1320
+ v->minorVersion = (MYSQL_VERSION_ID / 100) % 100;
1321
+ v->Type = 'M';
1322
+ ++v;
1323
+ v->majorVersion = TRANSACTD_VER_MAJOR;
1324
+ v->minorVersion = TRANSACTD_VER_MINOR;
1325
+ v->Type = 'T';
1326
+ req.paramMask = P_MASK_DATA | P_MASK_DATALEN;
1327
+ req.resultLen = sizeof(version) * 3;
1328
+ }
1329
+ else
1330
+ req.result = STATUS_BUFFERTOOSMALL;
1331
+ break;
1332
+ case TD_CLEAR_OWNERNAME:
1333
+ req.keybuf = (void_td*)"";
1334
+ case TD_SET_OWNERNAME:
1335
+ {
1336
+ database* db = getDatabaseCid(req.cid);
1337
+ m_tb = getTable(req.pbk->handle);
1338
+ int num = (req.keyNum > 1) ? req.keyNum - 2 : req.keyNum;
1339
+ num += '0';
1340
+ std::string s("%@%");
1341
+ s += (const char*)&num;
1342
+ s += (const char*)req.keybuf;
1343
+ req.result = ddl_execSql(
1344
+ db->thd(),
1345
+ makeSQLChangeTableComment(db->name(), m_tb->name(), s.c_str()));
1346
+ break;
1347
+ }
1348
+ case TD_ACL_RELOAD:
1349
+ req.result = getDatabaseCid(req.cid)->aclReload();
1350
+ break;
1240
1351
  }
1241
1352
  if (m_tb)
1242
1353
  m_tb->unUse();
1243
1354
  DEBUG_WRITELOG2(op, req)
1355
+ DEBUG_ERROR_MEMDUMP(req.result, "error", req.m_readBuffer, *((unsigned int*)req.m_readBuffer))
1356
+
1357
+
1244
1358
  size = req.serialize(m_tb, resultBuffer);
1245
1359
  short dymmy = 0;
1246
1360
  if ((req.result == 0) && (req.paramMask & P_MASK_BLOBBODY) &&
@@ -1255,15 +1369,20 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1255
1369
  return EXECUTE_RESULT_FORCSE_SYNC;
1256
1370
  return EXECUTE_RESULT_FORCSE_ASYNC;
1257
1371
  }
1372
+ if (req.result == ERROR_TD_INVALID_CLINETHOST)
1373
+ return EXECUTE_RESULT_ACCESS_DNIED;
1258
1374
  DEBUG_PROFILE_END_OP(1, op)
1259
1375
  return EXECUTE_RESULT_SUCCESS;
1260
1376
  }
1261
1377
 
1262
1378
  catch (bzs::rtl::exception& e)
1263
1379
  {
1380
+ const int* code = getCode(e);
1264
1381
  clenupNoException();
1382
+ DEBUG_ERROR_MEMDUMP(*code, "error", req.m_readBuffer, *((unsigned int*)req.m_readBuffer))
1383
+
1265
1384
  req.reset();
1266
- const int* code = getCode(e);
1385
+
1267
1386
  if (code)
1268
1387
  req.result = *code;
1269
1388
  else
@@ -1277,6 +1396,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1277
1396
  catch (...)
1278
1397
  {
1279
1398
  clenupNoException();
1399
+ DEBUG_ERROR_MEMDUMP(20001, "error", req.m_readBuffer, *((unsigned int*)req.m_readBuffer))
1280
1400
  req.reset();
1281
1401
  req.result = 20001;
1282
1402
  dumpStdErr(op, req, m_tb);
@@ -1297,8 +1417,48 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1297
1417
  return EXECUTE_RESULT_SUCCESS;
1298
1418
  }
1299
1419
 
1420
+ void makeRandomKey(unsigned char *buf, unsigned int size)
1421
+ {
1422
+ unsigned char *end= buf + size;
1423
+ std::random_device rnd;
1424
+ for (; buf < end; buf++)
1425
+ *buf = (unsigned char)(rnd() * 94 + 33);
1426
+ *buf= 0x00;
1427
+ }
1428
+
1429
+ size_t dbExecuter::getAcceptMessage(char* message, size_t size)
1430
+ {
1431
+ // make handshake packet
1432
+ m_authChecked = false;
1433
+ assert(size >= sizeof(trdVersiton));
1434
+
1435
+ handshale_t* hst = (handshale_t*)message;
1436
+ hst->options = 0;
1437
+ trdVersiton* ver = &hst->ver;
1438
+ hst->size = sizeof(handshale_t);
1439
+
1440
+ strcpy_s(ver->cherserServer, sizeof(ver->cherserServer),
1441
+ global_system_variables.collation_server->csname);
1442
+ ver->srvMajor = TRANSACTD_VER_MAJOR;
1443
+ ver->srvMinor = TRANSACTD_VER_MINOR;
1444
+ ver->srvRelease = TRANSACTD_VER_RELEASE;
1445
+ hst->transaction_isolation = getTransactdIsolation();
1446
+ hst->lock_wait_timeout = getTransactdLockWaitTimeout();
1447
+ if (strcmp(g_auth_type, AUTH_TYPE_MYSQL_STR) == 0)
1448
+ {
1449
+ makeRandomKey(m_scramble, MYSQL_SCRAMBLE_LENGTH);
1450
+ memcpy(hst->scramble, m_scramble, sizeof(hst->scramble));
1451
+
1452
+ }else
1453
+ {
1454
+ hst->scramble[0] = 0x00;
1455
+ hst->options |= HST_OPTION_NO_SCRAMBLE;
1456
+ hst->size -= sizeof(m_scramble);
1457
+ }
1458
+ return hst->size;
1459
+ }
1300
1460
  // ---------------------------------------------------------------------------
1301
- // class connMgrExecuter
1461
+ // class connMgrExecuter
1302
1462
  // ---------------------------------------------------------------------------
1303
1463
  connMgrExecuter::connMgrExecuter(request& req, unsigned __int64 parent)
1304
1464
  : m_req(req), m_modHandle(parent)
@@ -1354,11 +1514,11 @@ int connMgrExecuter::commandExec(netsvc::server::netWriter* nw)
1354
1514
  }
1355
1515
 
1356
1516
  // ---------------------------------------------------------------------------
1357
- // class commandExecuter
1517
+ // class commandExecuter
1358
1518
  // ---------------------------------------------------------------------------
1359
- commandExecuter::commandExecuter(__int64 parent) : m_modHandle(parent)
1519
+ commandExecuter::commandExecuter(netsvc::server::IAppModule* mod)
1360
1520
  {
1361
- m_dbExec.reset(new dbExecuter());
1521
+ m_dbExec.reset(new dbExecuter(mod));
1362
1522
  }
1363
1523
 
1364
1524
  commandExecuter::~commandExecuter()