transactd 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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,