transactd 2.3.0 → 2.4.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/{BUILD_UNIX-JA → BUILD_UNIX-JA.md} +6 -6
  3. data/CMakeLists.txt +20 -15
  4. data/{README-JA → README-JA.md} +23 -23
  5. data/{README → README.md} +22 -24
  6. data/RELEASE_NOTE +120 -0
  7. data/RELEASE_NOTE-JA +110 -0
  8. data/bin/common/tdclc_32_2_4.dll +0 -0
  9. data/bin/common/tdclc_64_2_4.dll +0 -0
  10. data/build/common/get_ruby_path.cmake +1 -1
  11. data/build/swig/ruby/tdclrb_wrap.cpp +1319 -830
  12. data/build/swig/tdcl.i +22 -2
  13. data/build/tdclc/tdclc.cbproj +1 -1
  14. data/build/tdclc/tdclc.rc +4 -4
  15. data/build/tdclcpp/tdclcpp.rc +4 -4
  16. data/build/tdclcpp/tdclcpp_bc.cbproj +2 -1
  17. data/build/tdclrb/CMakeLists.txt +6 -1
  18. data/build/tdclrb/bldgem/extconf.rb +5 -1
  19. data/build/tdclrb/tdclrb.rc +4 -4
  20. data/source/bzs/db/engine/mysql/database.cpp +44 -40
  21. data/source/bzs/db/engine/mysql/database.h +28 -8
  22. data/source/bzs/db/engine/mysql/dbManager.cpp +2 -0
  23. data/source/bzs/db/engine/mysql/dbManager.h +2 -7
  24. data/source/bzs/db/engine/mysql/mysqlInternal.h +79 -7
  25. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +5 -1
  26. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +32 -8
  27. data/source/bzs/db/protocol/tdap/client/activeTable.h +17 -4
  28. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
  29. data/source/bzs/db/protocol/tdap/client/client.cpp +51 -6
  30. data/source/bzs/db/protocol/tdap/client/client.h +41 -11
  31. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +51 -15
  32. data/source/bzs/db/protocol/tdap/client/connMgr.h +6 -1
  33. data/source/bzs/db/protocol/tdap/client/database.cpp +26 -5
  34. data/source/bzs/db/protocol/tdap/client/database.h +3 -2
  35. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +38 -28
  36. data/source/bzs/db/protocol/tdap/client/dbDef.h +1 -1
  37. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +2 -32
  38. data/source/bzs/db/protocol/tdap/client/field.cpp +0 -1
  39. data/source/bzs/db/protocol/tdap/client/filter.h +60 -33
  40. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +2 -5
  41. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +9 -0
  42. data/source/bzs/db/protocol/tdap/client/memRecord.h +1 -0
  43. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +99 -48
  44. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +5 -2
  45. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +76 -26
  46. data/source/bzs/db/protocol/tdap/client/nsTable.h +6 -4
  47. data/source/bzs/db/protocol/tdap/client/request.h +28 -11
  48. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +19 -11
  49. data/source/bzs/db/protocol/tdap/client/table.cpp +157 -70
  50. data/source/bzs/db/protocol/tdap/client/table.h +20 -5
  51. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +57 -4
  52. data/source/bzs/db/protocol/tdap/client/trdormapi.h +55 -20
  53. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +65 -31
  54. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +2 -0
  55. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +24 -36
  56. data/source/bzs/db/protocol/tdap/mysql/request.h +1 -1
  57. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +98 -18
  58. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +12 -7
  59. data/source/bzs/db/protocol/tdap/tdapRequest.h +3 -8
  60. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +1 -9
  61. data/source/bzs/db/protocol/tdap/tdapSchema.h +31 -1
  62. data/source/bzs/db/protocol/tdap/tdapcapi.h +49 -6
  63. data/source/bzs/db/protocol/tdap/uri.h +41 -6
  64. data/source/bzs/db/transactd/appModule.cpp +0 -1
  65. data/source/bzs/db/transactd/appModule.h +0 -2
  66. data/source/bzs/db/transactd/connManager.cpp +202 -33
  67. data/source/bzs/db/transactd/connManager.h +11 -4
  68. data/source/bzs/db/transactd/connectionRecord.h +19 -5
  69. data/source/bzs/db/transactd/transactd.cpp +39 -8
  70. data/source/bzs/env/crosscompile.cpp +1 -1
  71. data/source/bzs/example/queryData.cpp +1 -1
  72. data/source/bzs/netsvc/client/iconnection.h +2 -0
  73. data/source/bzs/netsvc/client/tcpClient.cpp +48 -26
  74. data/source/bzs/netsvc/client/tcpClient.h +171 -106
  75. data/source/bzs/netsvc/server/IAppModule.h +0 -1
  76. data/source/bzs/netsvc/server/serverPipe.cpp +5 -1
  77. data/source/bzs/netsvc/server/serverPipe.h +2 -1
  78. data/source/bzs/test/tdclatl/test_query_atl.js +105 -0
  79. data/source/bzs/test/tdclphp/transactd_Test.php +129 -11
  80. data/source/bzs/test/tdclrb/transactd_spec.rb +74 -2
  81. data/source/bzs/test/transactdBench/scaling_bench.cpp +1 -1
  82. data/source/bzs/test/trdclengn/test_trdclengn.cpp +45 -20
  83. data/source/global/tdclatl/Bookmark.cpp +28 -0
  84. data/source/global/tdclatl/Bookmark.h +65 -0
  85. data/source/global/tdclatl/Database.cpp +2 -2
  86. data/source/global/tdclatl/Database.h +1 -3
  87. data/source/global/tdclatl/DbDef.cpp +6 -0
  88. data/source/global/tdclatl/DbDef.h +1 -0
  89. data/source/global/tdclatl/QueryBase.cpp +29 -0
  90. data/source/global/tdclatl/QueryBase.h +4 -0
  91. data/source/global/tdclatl/Record.cpp +14 -2
  92. data/source/global/tdclatl/Record.h +1 -1
  93. data/source/global/tdclatl/Table.cpp +80 -16
  94. data/source/global/tdclatl/Table.h +23 -8
  95. data/source/global/tdclatl/_IDatabaseEvents_CP.h +39 -0
  96. data/source/global/tdclatl/activeTable.cpp +2 -2
  97. data/source/global/tdclatl/activeTable.h +1 -1
  98. data/source/global/tdclatl/tdclatl.idl +64 -14
  99. metadata +12 -12
  100. data/bin/common/tdclc_32_2_3.dll +0 -0
  101. data/bin/common/tdclc_64_2_3.dll +0 -0
  102. data/build/tdclcpp/BUILDNUMBER.txt +0 -1
  103. data/build/tdclrb/BUILDNUMBER.txt +0 -1
  104. /data/{BUILD_WIN-JA → BUILD_WIN-JA.md} +0 -0
  105. /data/{README_ORMSRCGEN-JA → README_ORMSRCGEN-JA.md} +0 -0
  106. /data/{README_ORMSRCGEN → README_ORMSRCGEN.md} +0 -0
@@ -32,6 +32,7 @@ typedef void* HANDLE;
32
32
  typedef void* HINSTANCE;
33
33
  #endif
34
34
  #include <bzs/db/protocol/tdap/tdapRequest.h>
35
+ #include <bzs/db/transactd/connectionRecord.h>
35
36
 
36
37
  #pragma package(smart_init)
37
38
 
@@ -144,8 +145,8 @@ struct nsdbimpl
144
145
  unsigned short id;
145
146
  short snapShotCount;
146
147
  nstable* tables[nsdatabase::maxtables];
147
- uchar_td clientID[16];
148
- uchar_td* cid() { return clientID; }
148
+ uchar_td cidPtr[16];
149
+ uchar_td* cid() { return cidPtr; }
149
150
  _TCHAR bdfPath[MAX_PATH];
150
151
  short tableCount;
151
152
  short lockWaitCount;
@@ -154,10 +155,12 @@ struct nsdbimpl
154
155
  bool uselongFilename;
155
156
  bool localSharing;
156
157
  bool ignoreTestPtr;
158
+ bool reconnected;
157
159
  nsdbimpl()
158
160
  : refCount(1), tranCount(0), id(0), snapShotCount(0), tableCount(0),
159
161
  lockWaitCount(10), lockWaitTime(100), uriMode(false),
160
- uselongFilename(false), localSharing(false), ignoreTestPtr(false)
162
+ uselongFilename(false), localSharing(false), ignoreTestPtr(false),
163
+ reconnected(false)
161
164
  {
162
165
  }
163
166
 
@@ -166,10 +169,10 @@ struct nsdbimpl
166
169
  id = id_;
167
170
 
168
171
  // make client id
169
- memset(clientID, 0, 12);
170
- clientID[12] = 'G';
171
- clientID[13] = 'X';
172
- memcpy(&clientID[14], &id, 2);
172
+ memset(cidPtr, 0, 12);
173
+ cidPtr[12] = 'G';
174
+ cidPtr[13] = 'X';
175
+ memcpy(&cidPtr[14], &id, 2);
173
176
  bdfPath[0] = 0x00;
174
177
  }
175
178
 
@@ -288,7 +291,14 @@ nsdatabase& nsdatabase::operator=(const nsdatabase& rt)
288
291
 
289
292
  int nsdatabase::enableTrn() const
290
293
  {
291
- return m_nsimpl->tranCount;
294
+ if (m_nsimpl)
295
+ return m_nsimpl->tranCount;
296
+ return 0;
297
+ }
298
+
299
+ bool nsdatabase::isReconnected() const
300
+ {
301
+ return m_nsimpl->reconnected;
292
302
  }
293
303
 
294
304
  short nsdatabase::stat() const
@@ -298,7 +308,7 @@ short nsdatabase::stat() const
298
308
 
299
309
  uchar_td* nsdatabase::clientID() const
300
310
  {
301
- return m_nsimpl->clientID;
311
+ return m_nsimpl->cidPtr;
302
312
  }
303
313
 
304
314
  short nsdatabase::openTableCount() const
@@ -409,7 +419,7 @@ void nsdatabase::createTable(fileSpec* pfs, uint_td len,
409
419
 
410
420
  m_stat =
411
421
  m_btrcallid(TD_CREATETABLE, posblk, pfs, &len, (void*)p,
412
- (uchar_td)strlen(p), (char_td)mode, m_nsimpl->clientID);
422
+ (uchar_td)strlen(p), (char_td)mode, m_nsimpl->cidPtr);
413
423
  }
414
424
 
415
425
  void nsdatabase::dropTable(const _TCHAR* pFullPath)
@@ -438,7 +448,7 @@ void nsdatabase::dropTable(const _TCHAR* pFullPath)
438
448
 
439
449
  m_stat =
440
450
  m_btrcallid(TD_CREATETABLE, posblk, NULL, NULL, (void*)p,
441
- (uchar_td)strlen(p) + 1, CR_SUBOP_DROP, m_nsimpl->clientID);
451
+ (uchar_td)strlen(p) + 1, CR_SUBOP_DROP, m_nsimpl->cidPtr);
442
452
  }
443
453
 
444
454
  void nsdatabase::swapTablename(const _TCHAR* Name1, const _TCHAR* Name2)
@@ -453,7 +463,7 @@ void nsdatabase::swapTablename(const _TCHAR* Name1, const _TCHAR* Name2)
453
463
 
454
464
  m_stat = m_btrcallid(TD_CREATETABLE, posblk, (void*)p, &len, (void*)p2,
455
465
  (uchar_td)strlen(p2), CR_SUBOP_SWAPNAME,
456
- m_nsimpl->clientID);
466
+ m_nsimpl->cidPtr);
457
467
  }
458
468
 
459
469
  void nsdatabase::rename(const _TCHAR* pFullPath, const _TCHAR* newName)
@@ -491,7 +501,7 @@ void nsdatabase::rename(const _TCHAR* pFullPath, const _TCHAR* newName)
491
501
 
492
502
  m_stat = m_btrcallid(TD_CREATETABLE, posblk, (void*)p, &len, (void*)bufNew,
493
503
  (uchar_td)strlen(bufNew), CR_SUBOP_RENAME,
494
- m_nsimpl->clientID);
504
+ m_nsimpl->cidPtr);
495
505
  }
496
506
 
497
507
  void nsdatabase::registerTable(nstable* tb)
@@ -572,9 +582,9 @@ void nsdatabase::reset()
572
582
  if (m_btrcallid)
573
583
  {
574
584
  m_stat = m_btrcallid(TD_RESET_CLIENT, NULL, NULL, NULL, NULL, 0, 0,
575
- m_nsimpl->clientID);
585
+ m_nsimpl->cidPtr);
576
586
  m_stat = m_btrcallid(TD_STOP_ENGINE, NULL, NULL, NULL, NULL, 0, 0,
577
- m_nsimpl->clientID);
587
+ m_nsimpl->cidPtr);
578
588
  if (m_stat == ERROR_TD_NOT_CONNECTED)
579
589
  m_stat = STATUS_SUCCESS;
580
590
  }
@@ -585,9 +595,23 @@ void nsdatabase::reset()
585
595
  void nsdatabase::beginSnapshot(short bias)
586
596
  {
587
597
  if (m_nsimpl->snapShotCount == 0)
598
+ {
588
599
  m_stat = m_btrcallid(TD_BEGIN_SHAPSHOT + bias, NULL, NULL, NULL, NULL, 0, 0,
589
- m_nsimpl->clientID);
590
- m_nsimpl->snapShotCount++;
600
+ m_nsimpl->cidPtr);
601
+ #ifdef TEST_RECONNECT
602
+ if (canRecoverNetError(m_stat))
603
+ {
604
+ reconnect();
605
+ if (m_stat) return;
606
+ m_stat = m_btrcallid(TD_BEGIN_SHAPSHOT + bias, NULL, NULL, NULL, NULL,
607
+ 0, 0, m_nsimpl->cidPtr);
608
+ }
609
+ #endif
610
+ if (m_stat == 0)
611
+ m_nsimpl->snapShotCount++;
612
+ }
613
+ else
614
+ m_nsimpl->snapShotCount++;
591
615
  }
592
616
 
593
617
  void nsdatabase::endSnapshot()
@@ -595,7 +619,9 @@ void nsdatabase::endSnapshot()
595
619
  m_nsimpl->snapShotCount--;
596
620
  if (m_nsimpl->snapShotCount == 0)
597
621
  m_stat = m_btrcallid(TD_END_SNAPSHOT, NULL, NULL, NULL, NULL, 0, 0,
598
- m_nsimpl->clientID);
622
+ m_nsimpl->cidPtr);
623
+ if (m_nsimpl->snapShotCount < 0)
624
+ m_nsimpl->snapShotCount = 0;
599
625
  }
600
626
 
601
627
  void nsdatabase::beginTrn(short BIAS)
@@ -603,7 +629,7 @@ void nsdatabase::beginTrn(short BIAS)
603
629
  if (m_nsimpl->tranCount == 0)
604
630
  {
605
631
  m_stat = m_btrcallid((ushort_td)(BIAS + TD_BEGIN_TRANSACTION), NULL,
606
- NULL, NULL, NULL, 0, 0, m_nsimpl->clientID);
632
+ NULL, NULL, NULL, 0, 0, m_nsimpl->cidPtr);
607
633
  if (m_stat == 0)
608
634
  m_nsimpl->tranCount++;
609
635
  }
@@ -618,7 +644,7 @@ void nsdatabase::endTrn()
618
644
  if (m_nsimpl->tranCount == 0)
619
645
  {
620
646
  m_stat = m_btrcallid(TD_END_TRANSACTION, NULL, NULL, NULL, NULL, 0, 0,
621
- m_nsimpl->clientID);
647
+ m_nsimpl->cidPtr);
622
648
 
623
649
  #ifdef _WIN32
624
650
  g_lastTrnTime = GetTickCount();
@@ -631,7 +657,7 @@ void nsdatabase::endTrn()
631
657
  void nsdatabase::abortTrn()
632
658
  {
633
659
  m_stat = m_btrcallid(TD_ABORT_TRANSACTION, NULL, NULL, NULL, NULL, 0, 0,
634
- m_nsimpl->clientID);
660
+ m_nsimpl->cidPtr);
635
661
 
636
662
  m_nsimpl->tranCount = 0;
637
663
  #ifdef _WIN32
@@ -643,14 +669,14 @@ ushort_td nsdatabase::trxIsolationServer() const
643
669
  {
644
670
  if (!isUseTransactd())
645
671
  return 0xFFFF;
646
- return *((ushort_td*)(m_nsimpl->clientID + sizeof(char*)));
672
+ return *((ushort_td*)(m_nsimpl->cidPtr + sizeof(char*)));
647
673
  }
648
674
 
649
675
  ushort_td nsdatabase::trxLockWaitTimeoutServer() const
650
676
  {
651
677
  if (!isUseTransactd())
652
678
  return 0xFFFF;
653
- return *((ushort_td*)(m_nsimpl->clientID + sizeof(char*) + sizeof(ushort_td)));
679
+ return *((ushort_td*)(m_nsimpl->cidPtr + sizeof(char*) + sizeof(ushort_td)));
654
680
  }
655
681
 
656
682
 
@@ -669,7 +695,7 @@ void nsdatabase::getBtrVersion(btrVersions* Vers, uchar_td* posblk)
669
695
  uint_td datalen = sizeof(btrVersions);
670
696
 
671
697
  m_stat = m_btrcallid(TD_VERSION, posblk, Vers, &datalen, NULL, 0, 0,
672
- m_nsimpl->clientID);
698
+ m_nsimpl->cidPtr);
673
699
  {
674
700
  bool remote = false;
675
701
  if (uriMode())
@@ -739,16 +765,23 @@ void nsdatabase::readDatabaseDirectory(_TCHAR* retBuf, uchar_td buflen)
739
765
  // keynum is drive name A=1 B=2 C=3 0=default
740
766
  char tmp[128];
741
767
  m_stat = m_btrcallid(TD_GETDIRECTORY, NULL, NULL, NULL, tmp, 128, 0,
742
- m_nsimpl->clientID);
768
+ m_nsimpl->cidPtr);
743
769
  toTChar(retBuf, tmp, buflen);
744
770
  }
745
771
 
746
772
  bool nsdatabase::connect(const _TCHAR* URI, bool newConnection)
747
773
  {
748
774
  if (isTransactdUri(URI))
775
+ {
749
776
  if (!setUseTransactd())
750
777
  return false;
778
+ }else
779
+ {
780
+ m_stat = 0;
781
+ if (_tcsstr(URI, _T("://")) == NULL)
782
+ return true;
751
783
 
784
+ }
752
785
  uint_td datalen = 0;
753
786
 
754
787
  char uri_a[MAX_PATH] = { 0x00 };
@@ -794,7 +827,7 @@ bool nsdatabase::disconnectForReconnectTest()
794
827
  }
795
828
 
796
829
  /* TD_RECONNECT data buffer structure
797
-
830
+
798
831
  1 byte keynum
799
832
  1 byte bookmark size
800
833
  n byte bookmark
@@ -806,7 +839,7 @@ void nsdatabase::doReconnect(nstable* tb)
806
839
  char uri_a[MAX_PATH] = { 0x00 };
807
840
  tb->abortBulkInsert();
808
841
  datalen = tb->buflen();
809
- tdap::posblk* pb = (tdap::posblk*)tb->posblk();
842
+ tdap::posblk* pb = (tdap::posblk*)tb->posblk();
810
843
  char* databuf = new char[datalen];
811
844
  databuf[0] = tb->keyNum();
812
845
  memcpy(databuf + 1, &pb->bookmarkLen, pb->bookmarkLen + 1);
@@ -817,41 +850,59 @@ void nsdatabase::doReconnect(nstable* tb)
817
850
  delete [] databuf;
818
851
  }
819
852
 
853
+ bool nsdatabase::doReopenTables()
854
+ {
855
+ // Indicate reconnected, that serverPrepared are invalid.
856
+ m_nsimpl->reconnected = true;
857
+ if (!doReopenDatabaseSchema()) return false;
858
+ //Whole table, restore position.
859
+ for (int i = 0 ;i <= m_nsimpl->tableCount; ++i)
860
+ {
861
+ nstable* tb = m_nsimpl->tables[i];
862
+ if (tb && tb->isOpen())
863
+ {
864
+ doReconnect(tb);
865
+ if (m_stat != 0) return false;
866
+ }
867
+ }
868
+ return (m_stat == 0);
869
+ }
870
+
871
+ bool reconnectSharedConnection(const void* ptr)
872
+ {
873
+ boost::mutex::scoped_lock lck(g_mutex);
874
+ for (int i = 0; i < MAX_BTRENGIN; ++i)
875
+ {
876
+ if (engins()[i])
877
+ {
878
+ void* p = (*((void**)engins()[i]->m_nsimpl->cidPtr));
879
+ if (p == ptr)
880
+ {
881
+ if (!engins()[i]->doReopenTables())
882
+ return false;
883
+ }
884
+ }
885
+ }
886
+ return true;
887
+ }
888
+
820
889
  bool nsdatabase::reconnect()
821
890
  {
822
891
  //Transactd only
823
892
  if (!isUseTransactd())
824
893
  return false;
894
+
825
895
  m_nsimpl->tranCount = 0;
826
896
  m_nsimpl->snapShotCount = 0;
827
-
828
-
829
897
  uint_td datalen = 0;
830
898
  char uri_a[MAX_PATH] = { 0x00 };
831
899
  const char* p = toServerUri(uri_a, MAX_PATH, m_nsimpl->bdfPath, true);
832
900
  m_stat = m_btrcallid(TD_CONNECT, NULL, NULL, &datalen, (void*)p,
833
- (keylen_td)(strlen(p) + 1),
901
+ (keylen_td)(strlen(p) + 1),
834
902
  LG_SUBOP_RECONNECT, clientID());
835
903
  if (m_stat) return false;
904
+ return reconnectSharedConnection((*(void**)m_nsimpl->cidPtr));
836
905
 
837
- //Whole table, restore position.
838
- nstable* lockedTable = NULL; //This is only one.
839
- for (int i=0;i<m_nsimpl->tableCount;++i)
840
- {
841
- nstable* tb = m_nsimpl->tables[i];
842
- if (tb && tb->isOpen())
843
- {
844
- tdap::posblk* pb = (tdap::posblk*)tb->posblk();
845
- if (pb->lock)
846
- lockedTable = tb;
847
- else
848
- doReconnect(tb);
849
- if (m_stat != 0) break;
850
- }
851
- }
852
- if (lockedTable)
853
- doReconnect(lockedTable);
854
- return (m_stat == 0);
855
906
  }
856
907
 
857
908
  bool nsdatabase::trnsactionFlushWaitStatus()
@@ -55,11 +55,11 @@ DLLLIB BTRCALLID_PTR getTrnsctdEntryPoint();
55
55
  class DLLLIB nsdatabase
56
56
  {
57
57
  friend class nstable;
58
-
58
+ friend bool reconnectSharedConnection(const void* ptr);
59
59
  struct nsdbimpl* m_nsimpl;
60
60
  nsdatabase(const nsdatabase&);
61
61
  static unsigned int m_execCodepage;
62
-
62
+ bool doReopenTables();
63
63
  protected:
64
64
  BTRCALLID_PTR m_btrcallid;
65
65
  short m_stat;
@@ -78,6 +78,8 @@ protected:
78
78
  void addref();
79
79
  void internalRelease() { nsdatabase::release(); }
80
80
  void doReconnect(nstable* tb);
81
+ virtual bool doReopenDatabaseSchema(){ return true; }
82
+
81
83
  public:
82
84
  nsdatabase();
83
85
  virtual void release();
@@ -123,6 +125,7 @@ public:
123
125
  bool disconnect(const _TCHAR* uri = _T(""));
124
126
  bool disconnectForReconnectTest(); //for connection brokn emulate
125
127
  bool reconnect();
128
+ bool isReconnected() const;
126
129
 
127
130
  static const int maxtables = 50;
128
131
  static bool trnsactionFlushWaitStatus();
@@ -49,7 +49,8 @@ namespace client
49
49
  struct nstimpl
50
50
  {
51
51
  nstimpl()
52
- : refCount(1), bulkIns(NULL), mode(0), shared(false), isOpen(false)
52
+ : refCount(1), bulkIns(NULL), percentage(0),bookmarkLen(0),mode(0),
53
+ shared(false), isOpen(false)
53
54
  {
54
55
  memset(posblk, 0 ,POS_BLOCK_SIZE);
55
56
  }
@@ -57,6 +58,7 @@ struct nstimpl
57
58
  bulkInsert* bulkIns;
58
59
  nsdatabase* nsdb;
59
60
  percentage_td percentage;
61
+ ushort_td bookmarkLen;
60
62
  bookmark_td bookmark;
61
63
  _TCHAR uri[MAX_PATH];
62
64
  uchar_td posblk[POS_BLOCK_SIZE];
@@ -126,16 +128,21 @@ _TCHAR* nstable::getErrorMessage(int errorCode, _TCHAR* buf, size_t size)
126
128
  : bm and keynumber are ingored.
127
129
  )
128
130
  */
129
- void nstable::unlock(bookmark_td bm)
131
+ void nstable::unlock(bookmark_td& bm)
130
132
  {
131
133
  void* db = m_pdata;
132
134
  if (m_keynum == -1)
133
135
  m_pdata = &bm;
134
- m_datalen = 4;
136
+ m_datalen = bookmarkLen();
135
137
  tdap(TD_UNLOCK);
136
138
  m_pdata = db;
137
139
  }
138
140
 
141
+ void nstable::unlock()
142
+ {
143
+ tdap(TD_UNLOCK);
144
+ }
145
+
139
146
  bool nstable::isUseTransactd() const
140
147
  {
141
148
  return nsdb()->isUseTransactd();
@@ -347,10 +354,6 @@ char_td nstable::mode() const
347
354
 
348
355
  void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
349
356
  {
350
- void* svm_keybuf = m_keybuf;
351
- char_td svm_keynum = m_keynum;
352
- keylen_td svm_keybuflen = m_keylen;
353
-
354
357
  if (m_impl->nsdb == NULL)
355
358
  {
356
359
  m_stat = STATUS_LMITS_MAX_TABLES;
@@ -376,6 +379,11 @@ void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
376
379
  }
377
380
  }
378
381
 
382
+ void* svm_keybuf = m_keybuf;
383
+ char_td svm_keynum = m_keynum;
384
+ keylen_td svm_keybuflen = m_keylen;
385
+ void* data_bak = m_pdata;
386
+
379
387
  // convert utf8 string
380
388
  char tmpName[MAX_PATH] = { 0x00 };
381
389
  const char* p = nsdatabase::toServerUri(tmpName, MAX_PATH, m_impl->uri,
@@ -389,6 +397,7 @@ void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
389
397
  m_keynum = mode;
390
398
 
391
399
  char ownerNameBuf[OWNERNAME_SIZE] = { 0x00 };
400
+
392
401
  if (NULL != ownerName && 0x00 != ownerName[0])
393
402
  {
394
403
  const char* p2 = toChar(ownerNameBuf, ownerName, OWNERNAME_SIZE);
@@ -397,21 +406,34 @@ void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
397
406
  if (m_datalen > 11)
398
407
  {
399
408
  m_stat = STATUS_TOO_LONG_OWNERNAME;
400
- return;
409
+ goto clean;
401
410
  }
411
+ if (m_datalen < sizeof(unsigned int))
412
+ m_datalen = sizeof(unsigned int);/* for bookmarklen*/
402
413
  }
403
414
  else
404
- m_datalen = 0;
405
-
415
+ {
416
+ m_impl->bookmarkLen = 0;
417
+ m_pdata = &m_impl->bookmarkLen;
418
+ m_datalen = sizeof(ushort_td);/* for bookmarklen*/
419
+ }
406
420
  tdap(TD_OPENTABLE);
407
421
  if (m_stat == STATUS_SUCCESS)
408
422
  {
409
423
  m_impl->isOpen = true;
410
424
  m_impl->mode = mode;
425
+ if (!isUseTransactd())
426
+ m_impl->bookmarkLen = BTRV_BOOKMARK_SIZE;
427
+ else if (m_impl->bookmarkLen == 0)
428
+ m_impl->bookmarkLen = BTRV_BOOKMARK_SIZE;
429
+ else if (m_impl->bookmarkLen == 0xFFFF) //No primary
430
+ m_impl->bookmarkLen = 0;
411
431
  }
432
+ clean:
412
433
  m_keybuf = svm_keybuf;
413
434
  m_keynum = svm_keynum;
414
435
  m_keylen = svm_keybuflen;
436
+ m_pdata = data_bak;
415
437
  }
416
438
 
417
439
  void nstable::doUpdate(eUpdateType type)
@@ -518,9 +540,9 @@ ushort_td nstable::doInsert(bool ncc)
518
540
  m_impl->bulkIns->insert((const char*)data(), m_datalen, this);
519
541
  else
520
542
  {
521
- tdap(TD_REC_INSERT);
522
543
  if (ncc)
523
544
  m_keynum = -1;
545
+ tdap(TD_REC_INSERT);
524
546
  if (m_stat == STATUS_SUCCESS)
525
547
  ins_rows = 1;
526
548
  }
@@ -570,25 +592,48 @@ void nstable::doAbortBulkInsert()
570
592
  m_stat = STATUS_SUCCESS;
571
593
  }
572
594
 
595
+ ushort_td nstable::bookmarkLen() const
596
+ {
597
+ return m_impl->bookmarkLen;
598
+ }
599
+
573
600
  bookmark_td nstable::bookmark()
574
601
  {
575
602
  void* db = m_pdata;
576
-
603
+ m_impl->bookmark.empty = true;
577
604
  m_pdata = &m_impl->bookmark;
578
- m_datalen = sizeof(bookmark_td);
605
+ m_datalen = m_impl->bookmarkLen;
579
606
  tdap(TD_BOOKMARK);
607
+ if (m_stat == 0)
608
+ m_impl->bookmark.empty = false;
580
609
  m_pdata = db;
581
610
 
582
611
  return m_impl->bookmark;
583
612
  }
584
613
 
585
- void nstable::seekByBookmark(bookmark_td bm, ushort_td LockBias)
614
+ void nstable::seekByBookmark(bookmark_td& bm, ushort_td lockBias)
615
+ {
616
+ seekByBookmark(&bm, lockBias);
617
+ }
618
+
619
+ void nstable::seekByBookmark(bookmark_td* bm, ushort_td lockBias)
586
620
  {
621
+ if (!bm)
622
+ {
623
+ m_stat = STATUS_INVALID_BOOKMARK;
624
+ return;
625
+ }
626
+
587
627
  int count = 0;
588
- memcpy(m_pdata, &bm, sizeof(bookmark_td));
628
+ if (m_buflen < (uint_td)m_impl->bookmarkLen)
629
+ {
630
+ m_buflen = m_impl->bookmarkLen;
631
+ m_pdata = realloc(m_pdata, m_buflen);
632
+ }
633
+ memcpy(m_pdata, bm, m_impl->bookmarkLen);
589
634
  m_datalen = m_buflen;
590
635
  m_keylen = m_keybuflen;
591
- tdap((ushort_td)(TD_MOVE_BOOKMARK + LockBias));
636
+ tdap((ushort_td)(TD_MOVE_BOOKMARK + lockBias));
592
637
  if (m_stat == STATUS_SUCCESS)
593
638
  onReadAfter();
594
639
  // TODO: This code has some problem.
@@ -598,7 +643,7 @@ void nstable::seekByBookmark(bookmark_td bm, ushort_td LockBias)
598
643
  m_buflen = m_buflen * 2;
599
644
  m_datalen = m_buflen;
600
645
  m_pdata = realloc(m_pdata, m_buflen);
601
- memcpy(m_pdata, &bm, sizeof(bookmark_td));
646
+ memcpy(m_pdata, bm, m_impl->bookmarkLen);
602
647
  tdap(TD_MOVE_BOOKMARK);
603
648
  if (m_stat == STATUS_SUCCESS)
604
649
  {
@@ -622,21 +667,17 @@ percentage_td nstable::getPercentage()
622
667
  return m_impl->percentage;
623
668
  }
624
669
 
625
- percentage_td nstable::getPercentage(bookmark_td bm)
670
+ percentage_td nstable::getPercentage(bookmark_td& bm)
626
671
  {
627
- void* db = m_pdata;
628
672
  char_td ky = m_keynum;
629
673
 
630
- m_pdata = &m_impl->percentage;
631
- m_datalen = sizeof(percentage_td);
674
+ memcpy(m_pdata, &bm, bookmarkLen());
675
+ m_datalen = std::max<int>(bookmarkLen(), sizeof(percentage_td));
632
676
  m_keynum = -1;
633
-
634
- m_impl->percentage = bm;
635
677
  m_keylen = m_keybuflen;
636
678
  tdap(TD_GET_PER);
679
+ memcpy(&m_impl->percentage, m_pdata, sizeof(percentage_td));
637
680
  m_impl->percentage &= 0xffff;
638
-
639
- m_pdata = db;
640
681
  m_keynum = ky;
641
682
 
642
683
  return m_impl->percentage;
@@ -812,8 +853,17 @@ void nstable::tdap(ushort_td op)
812
853
  case STATUS_FILE_LOCKED:
813
854
  Sleep(m_impl->nsdb->lockWaitTime());
814
855
  break;
815
-
816
856
  default:
857
+ #ifdef TEST_RECONNECT
858
+ if (canRecoverNetError(m_stat))
859
+ {
860
+ m_impl->nsdb->reconnect();
861
+ if (m_stat) return;
862
+ m_stat = ERROR_TD_NET_TIMEOUT;
863
+ LoopCount = -1;
864
+ break;
865
+ }
866
+ #endif
817
867
  return;
818
868
  }
819
869
  } while ((m_stat != STATUS_SUCCESS) &&
@@ -143,7 +143,7 @@ protected:
143
143
  */
144
144
  void destroy();
145
145
  void setShared();
146
-
146
+ void seekByBookmark(bookmark_td* bm, ushort_td lockBias = LOCK_BIAS_DEFAULT);
147
147
  public:
148
148
  explicit nstable(nsdatabase* pbe);
149
149
  void addref(void);
@@ -205,18 +205,20 @@ public:
205
205
  void stepLast(ushort_td lockBias = LOCK_BIAS_DEFAULT);
206
206
  void stepPrev(ushort_td lockBias = LOCK_BIAS_DEFAULT);
207
207
  void stepNext(ushort_td lockBias = LOCK_BIAS_DEFAULT);
208
+ ushort_td bookmarkLen() const ;
208
209
  bookmark_td bookmark();
209
- void seekByBookmark(bookmark_td bm, ushort_td lockBias = LOCK_BIAS_DEFAULT);
210
+ void seekByBookmark(bookmark_td& bm, ushort_td lockBias = LOCK_BIAS_DEFAULT);
210
211
  void seekByBookmark();
211
212
  percentage_td getPercentage();
212
- percentage_td getPercentage(bookmark_td bm);
213
+ percentage_td getPercentage(bookmark_td& bm);
213
214
  void seekByPercentage();
214
215
  void seekByPercentage(percentage_td pc);
215
216
  void setOwnerName(const _TCHAR* name, char_td enctype = 0);
216
217
  void clearOwnerName();
217
218
  ushort_td recordLength();
218
219
  void stats(void* databuffer, uint_td buflen, bool estimate = true);
219
- void unlock(bookmark_td bm = 0);
220
+ void unlock(bookmark_td& bm);
221
+ void unlock();
220
222
  char_td mode() const;
221
223
  static _TCHAR* getFileName(const _TCHAR* uri, _TCHAR* filename);
222
224
  static short_td tdapErr(HWND hWnd, short_td status,