transactd 2.1.0 → 2.2.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 (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
@@ -115,7 +115,6 @@ void onLoadLibrary(void)
115
115
  pthread_key_create(&g_tlsiID_SC2, cleanupCharPtr);
116
116
  if (tls_getspecific(g_tlsiID_SC3) == NULL)
117
117
  pthread_key_create(&g_tlsiID_SC3, cleanupCharPtr);
118
-
119
118
  #endif
120
119
  }
121
120
 
@@ -123,7 +122,6 @@ void onUnloadLibrary(void)
123
122
  {
124
123
  bzs::env::deinitCvtProcess();
125
124
  #if (defined(__APPLE__) && defined(USETLS))
126
- cleanupTls();
127
125
  pthread_key_delete(g_tlsiID_SC1);
128
126
  pthread_key_delete(g_tlsiID_SC2);
129
127
  pthread_key_delete(g_tlsiID_SC3);
@@ -820,6 +820,8 @@ void dbdef::create(const _TCHAR* fullpath)
820
820
  fs->keySpecs[0].keyType = 1; // Integer
821
821
  nsdb()->createTable(fs, 412, fullpath, 0);
822
822
  free(fs);
823
+
824
+ //TODO Create operation include set owner name.
823
825
  if (nsdb()->stat() == 0)
824
826
  { // set owner name
825
827
  ownerNameSetter* bao = new ownerNameSetter(nsdb());
@@ -162,8 +162,8 @@ void onUnloadLibrary(void)
162
162
  pthread_key_delete(g_tlsiID);
163
163
  pthread_key_delete(g_tlsiID1);
164
164
  pthread_key_delete(g_tlsiID_SC1);
165
- }
166
165
  #endif
166
+ }
167
167
  }
168
168
  #endif // NOT _WIN32
169
169
 
@@ -198,45 +198,6 @@ extern "C" PACKAGE_OSX short_td __STDCALL
198
198
  case TD_ADD_SENDBLOB:
199
199
  return client_t->addBlob((const bzs::db::blob*)data,
200
200
  (keyNum == TD_ASBLOB_ENDROW));
201
- case TD_OPENTABLE:
202
- case TD_CREATETABLE:
203
- client_t->connect();
204
- if (client_t->result() == 0)
205
- {
206
- if (op == TD_CREATETABLE)
207
- {
208
- if (client_t->getServerCharsetIndex() != -1)
209
- client_t->create();
210
- else
211
- {
212
- client_t->cleanup();
213
- return 1;
214
- }
215
- }
216
- else if (op == TD_OPENTABLE)
217
- client_t->req().paramMask = P_MASK_ALL;
218
- if (!client_t->buildDualChasetKeybuf())
219
- {
220
- client_t->cleanup();
221
- return SERVER_CLIENT_NOT_COMPATIBLE;
222
- }
223
- }
224
- break;
225
- case TD_CONNECT:
226
- {
227
- client_t->cmdConnect();
228
- break;
229
- }
230
- case TD_STASTISTICS:
231
- client_t->req().paramMask =
232
- P_MASK_DATALEN | P_MASK_KEYBUF | P_MASK_KEYNUM;
233
- break;
234
- case TD_RESET_CLIENT:
235
- client_t->req().paramMask = P_MASK_KEYONLY;
236
- break;
237
- case TD_DROP_INDEX:
238
- client_t->req().paramMask = P_MASK_POSBLK | P_MASK_KEYNUM;
239
- break;
240
201
  case TD_REC_INSERT:
241
202
  case TD_INSERT_BULK:
242
203
  case TD_REC_UPDATE:
@@ -247,8 +208,7 @@ extern "C" PACKAGE_OSX short_td __STDCALL
247
208
  break;
248
209
  case TD_MOVE_BOOKMARK:
249
210
  case TD_MOVE_PER:
250
- case TD_BUILD_INDEX:
251
- client_t->req().paramMask = P_MASK_NOKEYBUF;
211
+ client_t->req().paramMask = P_MASK_NOKEYBUF;
252
212
  break;
253
213
  case TD_UNLOCK:
254
214
  client_t->req().paramMask = P_MASK_POSBLK | P_MASK_KEYNUM;
@@ -349,6 +309,51 @@ extern "C" PACKAGE_OSX short_td __STDCALL
349
309
  }
350
310
  break;
351
311
  }
312
+ case TD_OPENTABLE:
313
+ case TD_CREATETABLE:
314
+ client_t->connect();
315
+ if (client_t->result() == 0)
316
+ {
317
+ if (op == TD_CREATETABLE)
318
+ {
319
+ if (client_t->getServerCharsetIndex() != -1)
320
+ client_t->create();
321
+ else
322
+ {
323
+ client_t->cleanup();
324
+ return 1;
325
+ }
326
+ }
327
+ else if (op == TD_OPENTABLE)
328
+ client_t->req().paramMask = P_MASK_ALL;
329
+ if (!client_t->buildDualChasetKeybuf())
330
+ {
331
+ client_t->cleanup();
332
+ return SERVER_CLIENT_NOT_COMPATIBLE;
333
+ }
334
+ }
335
+ break;
336
+ case TD_CONNECT:
337
+ {
338
+ client_t->cmdConnect();
339
+ break;
340
+ }
341
+ case TD_STASTISTICS:
342
+ client_t->req().paramMask =
343
+ P_MASK_DATALEN | P_MASK_KEYBUF | P_MASK_KEYNUM;
344
+ break;
345
+ case TD_RESET_CLIENT:
346
+ client_t->req().paramMask = P_MASK_KEYONLY;
347
+ break;
348
+ case TD_BUILD_INDEX:
349
+ client_t->createIndex();
350
+ break;
351
+ case TD_DROP_INDEX:
352
+ client_t->req().paramMask = P_MASK_POSBLK | P_MASK_KEYNUM;
353
+ break;
354
+ case TD_ACL_RELOAD:
355
+ client_t->req().paramMask = 0;
356
+ break;
352
357
  }
353
358
  short_td ret = client_t->execute();
354
359
  client_t->cleanup();
@@ -58,9 +58,11 @@ class refarymem
58
58
 
59
59
  protected:
60
60
 
61
- refarymem(const refarymem& r):m_parent(NULL),
61
+ refarymem(const refarymem& r):m_parent(NULL),
62
62
  m_child(0), m_allocType(MEM_ALLOC_TYPE_NONE){}
63
63
 
64
+ virtual ~refarymem(){}
65
+
64
66
  refarymem& operator=(const refarymem& r)
65
67
  {
66
68
  return *this;
@@ -978,9 +978,9 @@ class filter
978
978
 
979
979
 
980
980
  filter(table* tb)
981
- : m_tb(tb), m_extendBuflen(0), m_stat(0), m_preparedId(0),
982
- m_ignoreFields(false), m_seeksMode(false), m_useOptimize(true),
983
- m_withBookmark(true), m_seeksWritedCount(0), m_hasManyJoin(false),
981
+ : m_tb(tb), m_seeksWritedCount(0), m_extendBuflen(0), m_stat(0),
982
+ m_preparedId(0),m_ignoreFields(false), m_seeksMode(false),
983
+ m_useOptimize(true),m_withBookmark(true), m_hasManyJoin(false),
984
984
  m_preparingMode(false),m_ddba(false)
985
985
  {
986
986
  m_isTransactd = m_tb->isUseTransactd();
@@ -638,6 +638,21 @@ void nsdatabase::abortTrn()
638
638
  #endif
639
639
  }
640
640
 
641
+ ushort_td nsdatabase::trxIsolationServer() const
642
+ {
643
+ if (!isUseTransactd())
644
+ return 0xFFFF;
645
+ return *((ushort_td*)(m_nsimpl->clientID + sizeof(char*)));
646
+ }
647
+
648
+ ushort_td nsdatabase::trxLockWaitTimeoutServer() const
649
+ {
650
+ if (!isUseTransactd())
651
+ return 0xFFFF;
652
+ return *((ushort_td*)(m_nsimpl->clientID + sizeof(char*) + sizeof(ushort_td)));
653
+ }
654
+
655
+
641
656
  short_td nsdatabase::tdapErr(HWND hWnd, _TCHAR* retbuf)
642
657
  {
643
658
  return nstable::tdapErr(hWnd, m_stat, _T("Engin"), retbuf);
@@ -713,7 +728,7 @@ bool nsdatabase::isTransactdUri(const _TCHAR* uri)
713
728
  return (_tcsstr(uri, _T("tdap://")) != NULL);
714
729
  }
715
730
 
716
- bool nsdatabase::isUseTransactd()
731
+ bool nsdatabase::isUseTransactd() const
717
732
  {
718
733
  return (m_btrcallid == getTrnsctdEntryPoint());
719
734
  }
@@ -754,7 +769,8 @@ bool nsdatabase::disconnect(const _TCHAR* URI)
754
769
  char uri_a[MAX_PATH];
755
770
  const char* p = toServerUri(uri_a, MAX_PATH, URI, isUseTransactd());
756
771
  m_stat = m_btrcallid(TD_CONNECT, NULL, NULL, &datalen, (void*)p,
757
- (keylen_td)(strlen(p) + 1), 1, clientID());
772
+ (keylen_td)(strlen(p) + 1), LG_SUBOP_DISCONNECT,
773
+ clientID());
758
774
  if (m_stat)
759
775
  return false;
760
776
  return true;
@@ -105,18 +105,19 @@ public:
105
105
  void swapTablename(const _TCHAR* uri1, const _TCHAR* uri2);
106
106
  void beginTrn(short bias = SINGLELOCK_READ_COMMITED +
107
107
  NOWAIT_WRITE); // NoWit SingleLock
108
- // ���s�g�����U�N�V����
109
108
  void endTrn();
110
109
  void abortTrn();
111
110
  void beginSnapshot(short bias = CONSISTENT_READ);
112
111
  void endSnapshot();
112
+ ushort_td trxIsolationServer() const ;
113
+ ushort_td trxLockWaitTimeoutServer() const ;
113
114
  short_td tdapErr(HWND hWnd, _TCHAR* retbuf = NULL);
114
115
  bool useLongFilename();
115
116
  void setUseLongFilename(bool value);
116
117
  void getBtrVersion(btrVersions* versions, uchar_td* posblk);
117
118
  bool setUseTransactd();
118
119
  bool isTransactdUri(const _TCHAR* uri);
119
- bool isUseTransactd();
120
+ bool isUseTransactd() const;
120
121
  void readDatabaseDirectory(_TCHAR* retBuf, uchar_td len);
121
122
  bool connect(const _TCHAR* uri, bool newConnection = false);
122
123
  bool disconnect(const _TCHAR* uri = _T(""));
@@ -19,7 +19,7 @@
19
19
  #include "nsTable.h"
20
20
  #include "nsDatabase.h"
21
21
  #include "bulkInsert.h"
22
-
22
+ #include <bzs/db/protocol/tdap/uri.h>
23
23
  #include <limits.h>
24
24
  #include <string.h> // Required for _fstrstr()
25
25
  #include <stdio.h>
@@ -362,9 +362,10 @@ void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
362
362
  GetShortPathName(name, m_impl->uri, MAX_PATH);
363
363
  else
364
364
  #endif
365
+ {
365
366
  if (m_impl->uri != name)
366
- _tcscpy_s(m_impl->uri, MAX_PATH, name);
367
-
367
+ _tcscpy_s(m_impl->uri, MAX_PATH, name);
368
+ }
368
369
  // for trnasctd
369
370
  if (m_impl->nsdb->isTransactdUri(m_impl->uri))
370
371
  {
@@ -375,6 +376,7 @@ void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
375
376
  }
376
377
  }
377
378
 
379
+ // convert utf8 string
378
380
  char tmpName[MAX_PATH] = { 0x00 };
379
381
  const char* p = nsdatabase::toServerUri(tmpName, MAX_PATH, m_impl->uri,
380
382
  m_impl->nsdb->isUseTransactd());
@@ -752,6 +754,7 @@ ushort_td nstable::recordLength()
752
754
 
753
755
  void nstable::doCreateIndex(bool specifyKeyNum)
754
756
  {
757
+
755
758
  if (specifyKeyNum)
756
759
  m_keynum += ((uchar_td)0x80);
757
760
  tdap(TD_BUILD_INDEX);
@@ -835,7 +838,12 @@ short_td nstable::tdapErr(HWND hWnd, short_td status, const _TCHAR* TableName,
835
838
 
836
839
  #pragma warning(disable : 4996)
837
840
  if (retbuf)
838
- _stprintf(retbuf, _T("table_name:%s \n%s"), TableName, buf);
841
+ {
842
+ if (TableName && TableName[0])
843
+ _stprintf(retbuf, _T("table_name:%s \n%s"), TableName, buf);
844
+ else
845
+ _stprintf(retbuf, _T("%s"), buf);
846
+ }
839
847
  #pragma warning(default : 4996)
840
848
 
841
849
  if ((int)hWnd <= 0)
@@ -854,7 +862,7 @@ short_td nstable::tdapErr(HWND hWnd, short_td status, const _TCHAR* TableName,
854
862
  void nstable::throwError(const _TCHAR* caption, short statusCode)
855
863
  {
856
864
  _TCHAR tmp[1024] = { 0x00 };
857
- nstable::tdapErr(0x00, statusCode, _T("unknown"), tmp);
865
+ nstable::tdapErr(0x00, statusCode, NULL, tmp);
858
866
  _TCHAR tmp2[1024] = { 0x00 };
859
867
  _stprintf_s(tmp2, 1024, _T("%s\n%s\n"), caption, tmp);
860
868
  THROW_BZS_ERROR_WITH_CODEMSG(statusCode, tmp2);
@@ -879,7 +887,7 @@ _TCHAR* nstable::getDirURI(const _TCHAR* path, _TCHAR* buf)
879
887
  _tfullpath(buf, path, MAX_PATH);
880
888
  else
881
889
  #endif
882
- _tcscpy(buf, path);
890
+ stripAuth(path, buf, MAX_PATH);
883
891
  _TUCHAR* p = (_TUCHAR*)_tcsmrchr((const _TUCHAR*)buf, PSEPARATOR_C);
884
892
  _TUCHAR* p2 = (_TUCHAR*)_tcsmrchr((const _TUCHAR*)buf, '=');
885
893
  if (p && p2)
@@ -193,19 +193,19 @@ public:
193
193
  return doCommitBulkInsert(autoCommit);
194
194
  }
195
195
  void tdap(ushort_td op);
196
- void seekFirst(ushort_td lockBias = 0);
197
- void seekLast(ushort_td lockBias = 0);
198
- void seekPrev(ushort_td lockBias = 0);
199
- void seekNext(ushort_td lockBias = 0);
200
- void seek(ushort_td lockBias = 0);
201
- void seekGreater(bool orEqual, ushort_td lockBias = 0);
202
- void seekLessThan(bool orEqual, ushort_td lockBias = 0);
203
- void stepFirst(ushort_td lockBias = 0);
204
- void stepLast(ushort_td lockBias = 0);
205
- void stepPrev(ushort_td lockBias = 0);
206
- void stepNext(ushort_td lockBias = 0);
196
+ void seekFirst(ushort_td lockBias = LOCK_BIAS_DEFAULT);
197
+ void seekLast(ushort_td lockBias = LOCK_BIAS_DEFAULT);
198
+ void seekPrev(ushort_td lockBias = LOCK_BIAS_DEFAULT);
199
+ void seekNext(ushort_td lockBias = LOCK_BIAS_DEFAULT);
200
+ void seek(ushort_td lockBias = LOCK_BIAS_DEFAULT);
201
+ void seekGreater(bool orEqual, ushort_td lockBias = LOCK_BIAS_DEFAULT);
202
+ void seekLessThan(bool orEqual, ushort_td lockBias = LOCK_BIAS_DEFAULT);
203
+ void stepFirst(ushort_td lockBias = LOCK_BIAS_DEFAULT);
204
+ void stepLast(ushort_td lockBias = LOCK_BIAS_DEFAULT);
205
+ void stepPrev(ushort_td lockBias = LOCK_BIAS_DEFAULT);
206
+ void stepNext(ushort_td lockBias = LOCK_BIAS_DEFAULT);
207
207
  bookmark_td bookmark();
208
- void seekByBookmark(bookmark_td bm, ushort_td lockBias = 0);
208
+ void seekByBookmark(bookmark_td bm, ushort_td lockBias = LOCK_BIAS_DEFAULT);
209
209
  void seekByBookmark();
210
210
  percentage_td getPercentage();
211
211
  percentage_td getPercentage(bookmark_td bm);
@@ -172,7 +172,7 @@ private:
172
172
  {
173
173
  // At Join that if some base records reference to a joined
174
174
  // record
175
- // that the joined record pointer is shared by some
175
+ // that the joined record pointer is shared by some
176
176
  // base records.
177
177
  for (int i = 0; i < (int)rows; ++i)
178
178
  {
@@ -466,8 +466,11 @@ public:
466
466
  if (index != -1)
467
467
  return index;
468
468
  if (!noexception)
469
- THROW_BZS_ERROR_WITH_MSG(_T("groupQuery:Invalid key name"));
470
-
469
+ {
470
+ _TCHAR tmp[256];
471
+ _stprintf_s(tmp, 256, _T("groupQuery:Invalid key name '%s'."), name.c_str());
472
+ THROW_BZS_ERROR_WITH_MSG(tmp);
473
+ }
471
474
  return (key_type)m_fds->size();
472
475
  }
473
476
 
@@ -286,6 +286,7 @@ public:
286
286
 
287
287
  memcpy(p, keybuf, keylen);
288
288
  p += keylen;
289
+ // increment 1 byte
289
290
  *p = 0x00;
290
291
  ++p;
291
292
  }
@@ -191,11 +191,11 @@ const char* getFieldTypeName(uchar_td fieldType, int size, bool nobinary,
191
191
  return "";
192
192
  }
193
193
 
194
- FLAGS getKeyFlags(tabledef* table, short fieldNum)
194
+ FLAGS getKeyFlags(const tabledef* table, short fieldNum)
195
195
  {
196
196
  for (int i = 0; i < table->keyCount; i++)
197
197
  {
198
- keydef& key = table->keyDefs[i];
198
+ const keydef& key = table->keyDefs[i];
199
199
  for (int j = 0; j < key.segmentCount; j++)
200
200
  {
201
201
  if (key.segments[j].fieldNum == fieldNum)
@@ -217,12 +217,12 @@ bool isNumericFieldName(const char* name)
217
217
  return false;
218
218
  }
219
219
 
220
- bool isNULLKeySegment(tabledef* table, short fieldIndex)
220
+ bool isNULLKeySegment(const tabledef* table, short fieldIndex)
221
221
  {
222
222
  bool ret = 0;
223
223
  for (int i = 0; i < table->keyCount; i++)
224
224
  {
225
- keydef& key = table->keyDefs[i];
225
+ const keydef& key = table->keyDefs[i];
226
226
  for (int j = 0; j < key.segmentCount; j++)
227
227
  {
228
228
  if (key.segments[j].fieldNum == fieldIndex)
@@ -243,13 +243,13 @@ bool isNULLKeySegment(tabledef* table, short fieldIndex)
243
243
  return ret;
244
244
  }
245
245
 
246
- std::string getFiledList(tabledef* table, std::vector<std::string>& fdl)
246
+ std::string getFiledList(const tabledef* table, std::vector<std::string>& fdl)
247
247
  {
248
248
  std::string s;
249
249
  int len;
250
250
  for (int i = 0; i < table->fieldCount; i++)
251
251
  {
252
- fielddef& fd = table->fieldDefs[i];
252
+ const fielddef& fd = table->fieldDefs[i];
253
253
  s += "`";
254
254
  s += fdl[i];
255
255
  s += "` ";
@@ -260,7 +260,7 @@ std::string getFiledList(tabledef* table, std::vector<std::string>& fdl)
260
260
  characters in MySQL.
261
261
  Moreover, unicode cannot be specified by charset of the field. */
262
262
  if (fd.charsetIndex() == 0)
263
- fd.setCharsetIndex(table->charsetIndex);
263
+ const_cast<fielddef&>(fd).setCharsetIndex(table->charsetIndex);
264
264
  if ((fd.type == ft_myvarchar) || (fd.type == ft_mychar))
265
265
  len /= mysql::charsize(fd.charsetIndex());
266
266
  else if ((fd.type == ft_mywvarchar) || (fd.type == ft_mywchar))
@@ -283,7 +283,7 @@ std::string getFiledList(tabledef* table, std::vector<std::string>& fdl)
283
283
  return s;
284
284
  }
285
285
 
286
- void insertNisFields(tabledef* table, std::vector<std::string>& fdl,
286
+ void insertNisFields(const tabledef* table, std::vector<std::string>& fdl,
287
287
  std::string& s)
288
288
  {
289
289
  char buf[20];
@@ -291,7 +291,7 @@ void insertNisFields(tabledef* table, std::vector<std::string>& fdl,
291
291
  {
292
292
  _ltoa_s(i, buf, 20, 10);
293
293
  std::string fddef = "";
294
- keydef& key = table->keyDefs[i];
294
+ const keydef& key = table->keyDefs[i];
295
295
  if (key.segmentCount > 1)
296
296
  {
297
297
  if (key.segments[0].flags.bit9)
@@ -306,64 +306,71 @@ void insertNisFields(tabledef* table, std::vector<std::string>& fdl,
306
306
  }
307
307
  }
308
308
 
309
- std::string getKeyList(tabledef* table, std::vector<std::string>& fdl)
309
+ std::string& getKey(const tabledef* table, std::vector<std::string>& fdl,
310
+ int index, std::string& s, bool specifyKeyNum=false)
310
311
  {
311
312
  char buf[20];
312
- std::string s;
313
-
314
- for (int i = 0; i < table->keyCount; i++)
313
+ const keydef& key = table->keyDefs[index];
314
+ if (specifyKeyNum)
315
+ _ltoa_s(key.keyNumber, buf, 20, 10);
316
+ else
317
+ _ltoa_s(index, buf, 20, 10);
318
+ if ((table->primaryKeyNum == index) &&
319
+ (fdl[key.segments[0].fieldNum] == "auto_id_field"))
320
+ s += " PRIMARY KEY ";
321
+ else
315
322
  {
316
- keydef& key = table->keyDefs[i];
317
- _ltoa_s(i, buf, 20, 10);
318
- if ((table->primaryKeyNum == i) &&
319
- (fdl[key.segments[0].fieldNum] == "auto_id_field"))
320
- s += " PRIMARY KEY ";
323
+ if (key.segments[0].flags.bit0 == false)
324
+ s += " UNIQUE ";
321
325
  else
322
- {
323
- if (key.segments[0].flags.bit0 == false)
324
- s += " UNIQUE ";
325
- else
326
- s += " INDEX ";
327
- s += "key";
326
+ s += " INDEX ";
327
+ s += "key";
328
328
 
329
- s += buf;
330
- }
331
- s += "(";
329
+ s += buf;
330
+ }
331
+ s += "(";
332
332
 
333
- // "nf" segment is added to a head.
334
- if (key.segmentCount > 1)
333
+ // "nf" segment is added to a head.
334
+ if (key.segmentCount > 1)
335
+ {
336
+ // If a first segment is not 1 byte of Logical
337
+ const fielddef& fd = table->fieldDefs[key.segments[0].fieldNum];
338
+ if (!((fd.len == 1) && (fd.type == ft_logical)))
335
339
  {
336
- // If a first segment is not 1 byte of Logical
337
- fielddef& fd = table->fieldDefs[key.segments[0].fieldNum];
338
- if (!((fd.len == 1) && (fd.type == ft_logical)))
339
- {
340
- if (key.segments[0].flags.bit9)
341
- s += std::string("`") + "$nfn" + buf + "`,";
342
- else if (key.segments[0].flags.bit3)
343
- s += std::string("`") + "$nfa" + buf + "`,";
344
- }
340
+ if (key.segments[0].flags.bit9)
341
+ s += std::string("`") + "$nfn" + buf + "`,";
342
+ else if (key.segments[0].flags.bit3)
343
+ s += std::string("`") + "$nfa" + buf + "`,";
345
344
  }
346
- for (int j = 0; j < key.segmentCount; j++)
347
- {
348
- s += "`";
349
- s += fdl[key.segments[j].fieldNum];
350
- s += "`";
351
-
352
- // part key
353
- fielddef& fd = table->fieldDefs[key.segments[j].fieldNum];
354
- if (fd.keylen && ((fd.keylen != fd.len) || fd.blobLenBytes()))
355
- {
356
- sprintf_s(buf, 20, "(%d)", fd.keylen);
357
- s += buf;
358
- }
345
+ }
346
+ for (int j = 0; j < key.segmentCount; j++)
347
+ {
348
+ s += "`";
349
+ s += fdl[key.segments[j].fieldNum];
350
+ s += "`";
359
351
 
360
- if (key.segments[j].flags.bit6)
361
- s += " DESC";
362
- s += ",";
352
+ // part key
353
+ const fielddef& fd = table->fieldDefs[key.segments[j].fieldNum];
354
+ if (fd.keylen && ((fd.keylen != fd.len) || fd.blobLenBytes()))
355
+ {
356
+ sprintf_s(buf, 20, "(%d)", fd.keylen);
357
+ s += buf;
363
358
  }
364
- s.erase(s.end() - 1);
365
- s += "),";
359
+
360
+ if (key.segments[j].flags.bit6)
361
+ s += " DESC";
362
+ s += ",";
366
363
  }
364
+ s.erase(s.end() - 1);
365
+ s += "),";
366
+ return s;
367
+ }
368
+
369
+ std::string getKeyList(const tabledef* table, std::vector<std::string>& fdl)
370
+ {
371
+ std::string s;
372
+ for (int i = 0; i < table->keyCount; i++)
373
+ getKey(table, fdl, i, s);
367
374
  return s;
368
375
  }
369
376
 
@@ -381,15 +388,10 @@ std::string convertString(unsigned int toPage, unsigned int fromPage,
381
388
  return s;
382
389
  }
383
390
 
384
- std::string sqlCreateTable(const char* name /* utf8 */, tabledef* table,
385
- uchar_td charsetIndexServer)
391
+ // suffix added names list
392
+ void makeSuffixNamesList(const tabledef* table, std::vector<std::string>& fds)
386
393
  {
387
- // Duplication of a name is inspected and, in duplication, _1 is added.
388
- // It does not correspond to two or more duplications.
389
- std::string s = "CREATE TABLE `";
390
-
391
- std::vector<std::string> fdl;
392
- std::vector<std::string> fds;
394
+ std::vector<std::string> fdl;// lower case names list.
393
395
  char tmp[256];
394
396
  char num[10];
395
397
  for (int i = 0; i < table->fieldCount; i++)
@@ -407,6 +409,18 @@ std::string sqlCreateTable(const char* name /* utf8 */, tabledef* table,
407
409
  fds.push_back(fd.nameA());
408
410
  fdl.push_back(tmp);
409
411
  }
412
+ }
413
+
414
+ std::string sqlCreateTable(const char* name /* utf8 */, tabledef* table,
415
+ uchar_td charsetIndexServer)
416
+ {
417
+ // Duplication of a name is inspected and, in duplication, _1 is added.
418
+ // It does not correspond to two or more duplications.
419
+ std::string s = "CREATE TABLE `";
420
+
421
+ std::vector<std::string> fds;// suffix added names list
422
+ makeSuffixNamesList(table, fds);
423
+
410
424
  uint_td schemaCodePage =
411
425
  table->schemaCodePage ? table->schemaCodePage : GetACP();
412
426
  if ((name && name[0]))
@@ -434,6 +448,29 @@ std::string sqlCreateTable(const char* name /* utf8 */, tabledef* table,
434
448
  return s;
435
449
  }
436
450
 
451
+ std::string sqlCreateIndex(const tabledef* table, int keyNum,
452
+ bool specifyKeyNum, uchar_td charsetIndexServer)
453
+ {
454
+ std::string s;
455
+ std::vector<std::string> fds;// suffix added names list
456
+ makeSuffixNamesList(table, fds);
457
+ uint_td schemaCodePage =
458
+ table->schemaCodePage ? table->schemaCodePage : GetACP();
459
+ s += getFiledList(table, fds);
460
+ insertNisFields(table, fds, s);
461
+ s = "`";
462
+ s+= getFileName(table->fileNameA());
463
+ s += "` ADD";
464
+ getKey(table, fds, keyNum, s, specifyKeyNum);
465
+ s.erase(s.end() - 1);
466
+ // create statement charset must be server default charset.
467
+ // server default charset writen in my.cnf.
468
+ if (schemaCodePage != mysql::codePage(charsetIndexServer))
469
+ s = convertString(mysql::codePage(charsetIndexServer), schemaCodePage,
470
+ s.c_str());
471
+ return s;
472
+ }
473
+
437
474
  int findFieldNum(std::vector<fielddef>& fds, int pos)
438
475
  {
439
476
  for (int i = 0; i < (int)fds.size(); i++)
@@ -42,6 +42,9 @@ std::string sqlCreateTable(const char* name, tabledef* table,
42
42
  std::string sqlCreateTable(const char* fileName, fileSpec* fs,
43
43
  uchar_td charsetIndexServer);
44
44
 
45
+ std::string sqlCreateIndex(const tabledef* table, int keyNum,
46
+ bool specifyKeyNum, uchar_td charsetIndexServer);
47
+
45
48
  } // namespace client
46
49
  } // namespace tdap
47
50
  } // namespace protocol
@@ -671,19 +671,15 @@ const T* readBlob(char* ptr, ::bzs::rtl::stringBuffer* strBufs,
671
671
  if (len)
672
672
  {
673
673
  char** pc = (char**)(ptr + offset);
674
-
675
- if (len)
676
- {
677
- size_t olen = len * 2 + 1;
678
- result = strBufs->getPtr<T>(olen);
679
- if ((typeid(T) != typeid(char)) ||
680
- (cv->isNeedConvert() && (typeid(T) == typeid(char))))
681
- len = cv->revert(result, olen, *pc, len);
682
- else if (((T*)(*pc))[len] != 0x00)
683
- memcpy(result, *pc, len);
684
- else
685
- result = (T*)*pc;
686
- }
674
+ size_t olen = len * 2 + 1;
675
+ result = strBufs->getPtr<T>(olen);
676
+ if ((typeid(T) != typeid(char)) ||
677
+ (cv->isNeedConvert() && (typeid(T) == typeid(char))))
678
+ len = cv->revert(result, olen, *pc, len);
679
+ else if (((T*)(*pc))[len] != 0x00)
680
+ memcpy(result, *pc, len);
681
+ else
682
+ result = (T*)*pc;
687
683
  result[len] = 0x00;
688
684
 
689
685
  }else