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
@@ -31,13 +31,7 @@ namespace bzs
31
31
 
32
32
  namespace db
33
33
  {
34
- namespace engine
35
- {
36
- namespace mysql
37
- {
38
- class table;
39
- }
40
- }
34
+ namespace engine{ namespace mysql { class table; } }
41
35
 
42
36
  namespace protocol
43
37
  {
@@ -46,9 +40,17 @@ namespace tdap
46
40
  namespace client
47
41
  {
48
42
 
43
+ short errorCode(const boost::system::error_code& e);
44
+
49
45
  class request : public bzs::db::protocol::tdap::request,
50
46
  public bzs::netsvc::client::idirectReadHandler
51
47
  {
48
+
49
+ unsigned int handleError(const boost::system::error_code& e)
50
+ {
51
+ result = errorCode(e);
52
+ return 0;
53
+ }
52
54
  public:
53
55
  clientID* cid;
54
56
  request() : bzs::db::protocol::tdap::request(), cid(NULL){};
@@ -56,14 +58,20 @@ public:
56
58
  unsigned int onRead(unsigned int size, bzs::netsvc::client::connection* c) // orverride
57
59
  {
58
60
  unsigned int readlen = 0;
59
- readlen += c->directRead(&paramMask, sizeof(uint_td)); // paramMask and result
61
+ readlen += c->directRead(&paramMask, sizeof(uint_td)); // paramMask and result
62
+ if (c->error()) return handleError(c->error());
63
+
60
64
  if (P_MASK_POSBLK & paramMask)
65
+ {
61
66
  readlen += c->directRead(pbk, TD_POSBLK_TRANSMIT_SIZE);
62
-
67
+ if (c->error()) return handleError(c->error());
68
+ }
63
69
  if (P_MASK_DATALEN & paramMask)
64
70
  {
65
71
  uint_td tmp;
66
72
  readlen += c->directRead(&tmp, sizeof(uint_td));
73
+ if (c->error()) return handleError(c->error());
74
+
67
75
  if (*datalen < tmp)
68
76
  {
69
77
  result = STATUS_BUFFERTOOSMALL;
@@ -75,7 +83,10 @@ public:
75
83
  data = pbk->allocFunc(pbk->tb, tmp);
76
84
  *datalen = tmp;
77
85
  if (P_MASK_DATA & paramMask)
86
+ {
78
87
  readlen += c->directRead(data, *datalen);
88
+ if (c->error()) return handleError(c->error());
89
+ }
79
90
  }
80
91
  }
81
92
 
@@ -83,6 +94,7 @@ public:
83
94
  {
84
95
  keylen_td tmp;
85
96
  readlen += c->directRead(&tmp, sizeof(keylen_td));
97
+ if (c->error()) return handleError(c->error());
86
98
  if (keylen < tmp)
87
99
  {
88
100
  result = STATUS_KEYBUFFERTOOSMALL;
@@ -91,13 +103,18 @@ public:
91
103
  memset(keybuf, 0, keylen);
92
104
  keylen = tmp;
93
105
  readlen += c->directRead(keybuf, keylen);
106
+ if (c->error()) return handleError(c->error());
94
107
  }
95
108
  if (P_MASK_KEYNUM & paramMask)
109
+ {
96
110
  readlen += c->directRead(&keyNum, sizeof(char_td));
97
-
111
+ if (c->error()) return handleError(c->error());
112
+ }
98
113
  if (paramMask & P_MASK_BLOBBODY)
99
114
  {
100
- blobHeader = (const bzs::db::blobHeader*)c->directReadRemain(size - readlen);
115
+ blobHeader =
116
+ (const bzs::db::blobHeader*)c->directReadRemain(size - readlen);
117
+ if (c->error()) return handleError(c->error());
101
118
  readlen = size;
102
119
  if (blobHeader->rows)
103
120
  blobHeader->resetCur();
@@ -71,6 +71,8 @@ char g_buf[TMP_BUFSIZE];
71
71
  #define NOTE_TYPE 12
72
72
  #define VAR_TYPE 13
73
73
 
74
+ #define NIS_FD_KEYSEG_LIMIT 1
75
+
74
76
  const char* getFieldTypeName(uchar_td fieldType, int size, bool nobinary,
75
77
  const char* charsetName)
76
78
  {
@@ -284,6 +286,17 @@ std::string getFiledList(const tabledef* table, std::vector<std::string>& fdl)
284
286
  return s;
285
287
  }
286
288
 
289
+ bool isNeedNis(const tabledef* table, const keydef& key)
290
+ {
291
+ if (key.segmentCount > NIS_FD_KEYSEG_LIMIT)
292
+ {
293
+ // If a first segment is not 1 byte of Logical
294
+ const fielddef& fd = table->fieldDefs[key.segments[0].fieldNum];
295
+ return (!((fd.len == 1) && (fd.type == ft_logical)));
296
+ }
297
+ return false;
298
+ }
299
+
287
300
  void insertNisFields(const tabledef* table, std::vector<std::string>& fdl,
288
301
  std::string& s)
289
302
  {
@@ -293,7 +306,7 @@ void insertNisFields(const tabledef* table, std::vector<std::string>& fdl,
293
306
  _ltoa_s(i, buf, 20, 10);
294
307
  std::string fddef = "";
295
308
  const keydef& key = table->keyDefs[i];
296
- if (key.segmentCount > 1)
309
+ if (isNeedNis(table, key))
297
310
  {
298
311
  if (key.segments[0].flags.bit9)
299
312
  fddef = std::string("`") + "$nfn" + buf +
@@ -332,17 +345,12 @@ std::string& getKey(const tabledef* table, std::vector<std::string>& fdl,
332
345
  s += "(";
333
346
 
334
347
  // "nf" segment is added to a head.
335
- if (key.segmentCount > 1)
348
+ if (isNeedNis(table, key))
336
349
  {
337
- // If a first segment is not 1 byte of Logical
338
- const fielddef& fd = table->fieldDefs[key.segments[0].fieldNum];
339
- if (!((fd.len == 1) && (fd.type == ft_logical)))
340
- {
341
- if (key.segments[0].flags.bit9)
342
- s += std::string("`") + "$nfn" + buf + "`,";
343
- else if (key.segments[0].flags.bit3)
344
- s += std::string("`") + "$nfa" + buf + "`,";
345
- }
350
+ if (key.segments[0].flags.bit9)
351
+ s += std::string("`") + "$nfn" + buf + "`,";
352
+ else if (key.segments[0].flags.bit3)
353
+ s += std::string("`") + "$nfa" + buf + "`,";
346
354
  }
347
355
  for (int j = 0; j < key.segmentCount; j++)
348
356
  {
@@ -29,6 +29,7 @@
29
29
  #include <bzs/rtl/stringBuffers.h>
30
30
  #include "stringConverter.h"
31
31
  #include <boost/timer.hpp>
32
+ #include <boost/thread/mutex.hpp>
32
33
 
33
34
  #pragma package(smart_init)
34
35
 
@@ -60,8 +61,8 @@ class recordCache;
60
61
 
61
62
  struct tbimpl
62
63
  {
63
-
64
- void* bookMarks;
64
+ boost::mutex bookmarkMutex;
65
+ uchar_td* bookMarks;
65
66
  client::fields fields;
66
67
  pq_handle filterPtr;
67
68
  recordCache* rc;
@@ -71,8 +72,9 @@ struct tbimpl
71
72
  void* bfAtcPtr;
72
73
  void* optionalData;
73
74
  uint_td dataBufferLen;
74
- int bookMarksMemSize;
75
- int maxBookMarkedCount;
75
+ unsigned int bookMarksMemSize;
76
+ unsigned int maxBookMarkedCount;
77
+ recordCountFn onRecordCountFunc;
76
78
  char keybuf[MAX_KEYLEN];
77
79
  char keyNumIndex[128];
78
80
 
@@ -87,7 +89,7 @@ struct tbimpl
87
89
  : bookMarks(NULL), fields(tb), rc(NULL), mraPtr(NULL),
88
90
  dataBak(NULL), smartUpDate(NULL), bfAtcPtr(NULL), optionalData(NULL),
89
91
  dataBufferLen(0), bookMarksMemSize(0), maxBookMarkedCount(0),
90
- smartUpDateFlag(false), dataPacked(false)
92
+ onRecordCountFunc(NULL), smartUpDateFlag(false), dataPacked(false)
91
93
  {
92
94
  memset(&keyNumIndex[0], 0, 128);
93
95
  }
@@ -101,6 +103,62 @@ struct tbimpl
101
103
  if (bookMarks)
102
104
  free(bookMarks);
103
105
  }
106
+
107
+ inline void resetBookmarks()
108
+ {
109
+ boost::mutex::scoped_lock lck(bookmarkMutex);
110
+ maxBookMarkedCount = 0;
111
+ }
112
+
113
+ inline uchar_td* bookmarks(unsigned int index, ushort_td len)
114
+ {
115
+ boost::mutex::scoped_lock lck(bookmarkMutex);
116
+ unsigned int pos = index * (len + 2) + 2;
117
+ if ((index < maxBookMarkedCount) && bookMarks)
118
+ return bookMarks + pos;
119
+ return NULL;
120
+ }
121
+
122
+ /*inline bookmark_td* bookmarksPtr(unsigned int index)
123
+ {
124
+ boost::mutex::scoped_lock lck(bookmarkMutex);
125
+ unsigned int pos = index * 6 + 2;
126
+ if ((index < maxBookMarkedCount) && bookMarks)
127
+ return (bookmark_td*)((char*)bookMarks + pos);
128
+ return NULL;
129
+ }*/
130
+
131
+ inline short insertBookmarks(unsigned int start, void* data, ushort_td len,
132
+ ushort_td count)
133
+ {
134
+ unsigned int size = (start + count) * (2 + len);
135
+ boost::mutex::scoped_lock lck(bookmarkMutex);
136
+ if (!bookMarks)
137
+ {
138
+ bookMarks = (uchar_td*)malloc(BOOKMARK_ALLOC_SIZE);
139
+ if (bookMarks)
140
+ bookMarksMemSize = BOOKMARK_ALLOC_SIZE;
141
+ else
142
+ return STATUS_CANT_ALLOC_MEMORY;
143
+ }
144
+
145
+ if (bookMarksMemSize < size)
146
+ {
147
+ bookMarks = (uchar_td*)realloc(bookMarks, size + BOOKMARK_ALLOC_SIZE);
148
+ bookMarksMemSize = size + BOOKMARK_ALLOC_SIZE;
149
+ }
150
+ if (bookMarks)
151
+ {
152
+ //if (start + count > m_impl->maxBookMarkedCount)
153
+ memcpy(bookMarks + (start * (2 + len)), data,
154
+ count * (2 + len));
155
+ maxBookMarkedCount = start + count;
156
+ }
157
+ else
158
+ return STATUS_CANT_ALLOC_MEMORY;
159
+ return STATUS_SUCCESS;
160
+ }
161
+
104
162
  };
105
163
 
106
164
  // ---------------------------------------------------------------------------
@@ -123,7 +181,7 @@ class recordCache
123
181
  unsigned int m_len;
124
182
  unsigned int m_unpackLen;
125
183
  unsigned int m_rowCount;
126
- bookmark_td m_bookmark;
184
+ uchar_td* m_bookmark;
127
185
  uchar_td* m_ptr;
128
186
  uchar_td* m_tmpPtr;
129
187
  blobHeader* m_hd;
@@ -156,7 +214,7 @@ public:
156
214
  m_ptr += DATASIZE_BYTE;
157
215
  if (bookmarkSize)
158
216
  {
159
- m_bookmark = *((bookmark_td*)(m_ptr));
217
+ m_bookmark = m_ptr;
160
218
  m_ptr += bookmarkSize;
161
219
  }
162
220
  }
@@ -302,7 +360,7 @@ public:
302
360
  m_ptr += DATASIZE_BYTE;
303
361
  if (m_filter->bookmarkSize())
304
362
  {
305
- m_bookmark = *((bookmark_td*)(m_ptr));
363
+ m_bookmark = m_ptr;
306
364
  m_ptr += m_filter->bookmarkSize();
307
365
  }
308
366
  m_tmpPtr = data + totalSize;
@@ -371,7 +429,7 @@ public:
371
429
  }
372
430
 
373
431
  inline unsigned int len() const { return m_unpackLen; };
374
- inline bookmark_td bookmarkCurRow() const { return m_bookmark; };
432
+ inline uchar_td* bookmarkCurRow() const { return m_bookmark; };
375
433
  inline int row() const { return m_row; }
376
434
 
377
435
  inline int rowCount() const { return m_rowCount; }
@@ -500,41 +558,6 @@ fields& table::fields()
500
558
  return m_impl->fields;
501
559
  }
502
560
 
503
- void table::setBookMarks(int StartId, void* Data, ushort_td Count)
504
- {
505
- long size = (StartId + Count) * 6;
506
-
507
- if (!m_impl->bookMarks)
508
- {
509
- m_impl->bookMarks = malloc(BOOKMARK_ALLOC_SIZE);
510
- if (m_impl->bookMarks)
511
- m_impl->bookMarksMemSize = BOOKMARK_ALLOC_SIZE;
512
- else
513
- {
514
- m_stat = STATUS_CANT_ALLOC_MEMORY;
515
- return;
516
- }
517
- }
518
-
519
- if (m_impl->bookMarksMemSize < size)
520
- {
521
-
522
- m_impl->bookMarks =
523
- realloc(m_impl->bookMarks, size + BOOKMARK_ALLOC_SIZE);
524
- m_impl->bookMarksMemSize = size + BOOKMARK_ALLOC_SIZE;
525
- }
526
- if (m_impl->bookMarks)
527
- {
528
- if (StartId + Count - 1 > m_impl->maxBookMarkedCount)
529
- m_impl->maxBookMarkedCount = StartId + Count - 1;
530
- memcpy((void*)((char*)m_impl->bookMarks + ((StartId - 1) * 6)), Data,
531
- Count * 6);
532
- }
533
- else
534
- m_stat = STATUS_CANT_ALLOC_MEMORY;
535
- return;
536
- }
537
-
538
561
  inline short calcNextReadRecordCount(ushort_td curCount, int eTime)
539
562
  {
540
563
  ushort_td ret = curCount;
@@ -550,6 +573,22 @@ inline short calcNextReadRecordCount(ushort_td curCount, int eTime)
550
573
  return ret;
551
574
  }
552
575
 
576
+ void table::setOnRecordCount(const recordCountFn v)
577
+ {
578
+ m_impl->onRecordCountFunc = v;
579
+ }
580
+
581
+ recordCountFn table::onRecordCount() const
582
+ {
583
+ return m_impl->onRecordCountFunc;
584
+ }
585
+
586
+ void table::onRecordCounting(size_t count, bool& complate)
587
+ {
588
+ if (m_impl->onRecordCountFunc)
589
+ m_impl->onRecordCountFunc(this, (int)count, complate);
590
+ }
591
+
553
592
  uint_td table::doRecordCount(bool estimate, bool fromCurrent)
554
593
  {
555
594
  uint_td result = 0;
@@ -584,11 +623,14 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
584
623
 
585
624
  bookmark_td bm = bookmark();
586
625
 
626
+
587
627
  ushort_td tmpRejectCount = filter->rejectCount();
588
628
  ushort_td tmpRecCount = filter->recordCount();
589
629
 
590
630
  filter->setIgnoreFields(true);
591
- m_impl->maxBookMarkedCount = 0;
631
+ m_impl->resetBookmarks();
632
+ bool withBookmark = filter->withBookmark();
633
+
592
634
  if (fromCurrent)
593
635
  m_stat = curStat;
594
636
  else if (op == TD_KEY_NEXT_MULTI)
@@ -629,11 +671,11 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
629
671
  }
630
672
  recCountOnce = calcNextReadRecordCount(recCountOnce, eTime);
631
673
  filter->setMaxRows(recCountOnce);
632
- result += *((ushort_td*)m_pdata/*m_impl->dataBak*/);
633
- setBookMarks(m_impl->maxBookMarkedCount + 1,
634
- (void*)((char*)m_pdata/*m_impl->dataBak*/ + 2),
635
- *((ushort_td*)m_pdata/*m_impl->dataBak*/));
636
- m_impl->maxBookMarkedCount = result;
674
+ result += *((ushort_td*)m_pdata);
675
+ if (withBookmark)
676
+ insertBookmarks(m_impl->maxBookMarkedCount,
677
+ (void*)((char*)m_pdata + 2), *((ushort_td*)m_pdata));
678
+
637
679
  onRecordCounting(result, Complete);
638
680
  if (Complete)
639
681
  break;
@@ -648,7 +690,7 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
648
690
  filter->setIgnoreFields(false);
649
691
  filter->setMaxRows(tmpRecCount);
650
692
 
651
- if (bm)
693
+ if (!bm.empty)
652
694
  seekByBookmark(bm);
653
695
  m_impl->exBookMarking = false;
654
696
  m_stat = tmpStat;
@@ -781,10 +823,13 @@ short table::statReasonOfFind() const
781
823
 
782
824
  bookmark_td table::bookmarkFindCurrent() const
783
825
  {
784
-
826
+ bookmark_td bm;
785
827
  if (!m_impl->rc->isEndOfRow(m_impl->rc->row()))
786
- return m_impl->rc->bookmarkCurRow();
787
- return 0;
828
+ {
829
+ memcpy(bm.val, m_impl->rc->bookmarkCurRow(), bookmarkLen());
830
+ bm.empty = false;
831
+ }
832
+ return bm;
788
833
  }
789
834
 
790
835
  inline bool checkStatus(short v)
@@ -876,7 +921,13 @@ void table::btrvSeekMulti()
876
921
  }
877
922
  else
878
923
  {
879
- tdap((ushort_td)(TD_KEY_SEEK));
924
+ if (m_impl->filterPtr->isSeekByBookmarks())
925
+ {
926
+ memcpy(m_pdata, m_impl->keybuf, bookmarkLen());
927
+ m_datalen = m_buflen;
928
+ tdap((ushort_td)(TD_MOVE_BOOKMARK));
929
+ }else
930
+ tdap((ushort_td)(TD_KEY_SEEK));
880
931
  if (!doSeekMultiAfter(i))
881
932
  return;
882
933
  }
@@ -1090,9 +1141,11 @@ void table::setPrepare(const pq_handle stmt)
1090
1141
  }
1091
1142
  m_impl->rc->reset();
1092
1143
  m_impl->exBookMarking = false;
1093
- m_impl->maxBookMarkedCount = 0;
1144
+ m_impl->resetBookmarks();
1094
1145
  if (m_impl->filterPtr != stmt)
1095
1146
  m_impl->filterPtr = stmt;
1147
+ if (nsdb()->isReconnected())
1148
+ m_impl->filterPtr->setServerPreparedId(0);
1096
1149
  }
1097
1150
 
1098
1151
  pq_handle table::setQuery(const queryBase* query, bool serverPrepare)
@@ -1101,7 +1154,7 @@ pq_handle table::setQuery(const queryBase* query, bool serverPrepare)
1101
1154
  m_stat = 0;
1102
1155
  m_impl->rc->reset();
1103
1156
  m_impl->exBookMarking = false;
1104
- m_impl->maxBookMarkedCount = 0;
1157
+ m_impl->resetBookmarks();
1105
1158
  m_impl->filterPtr.reset();
1106
1159
  if (query == NULL)
1107
1160
  return m_impl->filterPtr;
@@ -1510,9 +1563,8 @@ uint_td table::unPack(char* ptr, size_t size)
1510
1563
  if (fd.type == ft_myfixedbinary)
1511
1564
  {
1512
1565
  int dl = *((unsigned short*)(pos));
1513
- assert(dl == fd.len - 2);
1514
1566
  memmove(pos, pos + 2, dl);
1515
- pos += dl;
1567
+ pos += fd.len - 2;
1516
1568
  *((unsigned short*)(pos)) = 0x00;
1517
1569
  ;
1518
1570
  pos += 2;
@@ -1918,23 +1970,42 @@ unsigned int table::getRecordHash()
1918
1970
  return hash((const char*)fieldPtr(0), datalen());
1919
1971
  }
1920
1972
 
1921
- int table::bookMarksCount() const
1973
+ void table::insertBookmarks(unsigned int start, void* data, ushort_td count)
1922
1974
  {
1923
- int ret;
1924
- ret = m_impl->maxBookMarkedCount;
1925
- return ret;
1975
+ m_stat = m_impl->insertBookmarks(start, data, bookmarkLen(), count);
1926
1976
  }
1927
1977
 
1928
- void table::moveBookmarksId(long id)
1978
+ int table::bookmarksCount() const
1929
1979
  {
1930
- long Point = (id - 1) * 6 + 2;
1980
+ return m_impl->maxBookMarkedCount;
1981
+ }
1931
1982
 
1932
- if ((id <= m_impl->maxBookMarkedCount) && (m_impl->bookMarks))
1933
- seekByBookmark(*((bookmark_td*)((char*)m_impl->bookMarks + Point)));
1934
- else
1935
- seekByBookmark(0);
1983
+ void table::moveBookmarks(unsigned int index)
1984
+ {
1985
+ seekByBookmark((bookmark_td*)m_impl->bookmarks(index, bookmarkLen()));
1986
+ }
1987
+
1988
+ bookmark_td table::bookmarks(unsigned int index) const
1989
+ {
1990
+ bookmark_td bm;
1991
+ uchar_td* p = m_impl->bookmarks(index, bookmarkLen());
1992
+ if (p)
1993
+ {
1994
+ memcpy(bm.val, p, bookmarkLen());
1995
+ bm.empty = false;
1996
+ }else
1997
+ {
1998
+ bm.empty = true;
1999
+ m_stat = STATUS_PROGRAM_ERROR;
2000
+ }
2001
+ return bm;
1936
2002
  }
1937
2003
 
2004
+ /*bookmark_td* table::bookmarksPtr(unsigned int index) const
2005
+ {
2006
+ return m_impl->bookmarksPtr(index);
2007
+ }*/
2008
+
1938
2009
  short_td table::doBtrvErr(HWND hWnd, _TCHAR* retbuf)
1939
2010
  {
1940
2011
  return nstable::tdapErr(hWnd, m_stat, (*m_tableDef)->tableName(), retbuf);
@@ -2120,7 +2191,8 @@ struct impl
2120
2191
  impl()
2121
2192
  : m_reject(1), m_limit(0), m_joinKeySize(0),
2122
2193
  m_optimize(queryBase::none), m_direction(table::findForword),
2123
- m_nofilter(false), m_withBookmark(false), m_stopAtLimit(false)
2194
+ m_nofilter(false), m_withBookmark(false), m_stopAtLimit(false),
2195
+ m_seekByBookmarks(false)
2124
2196
  {
2125
2197
  }
2126
2198
 
@@ -2139,6 +2211,7 @@ struct impl
2139
2211
  {
2140
2212
  bool m_withBookmark : 1;
2141
2213
  bool m_stopAtLimit : 1;
2214
+ bool m_seekByBookmarks : 1;
2142
2215
  };
2143
2216
  };
2144
2217
 
@@ -2223,6 +2296,7 @@ void queryBase::addSeekKeyValue(const _TCHAR* value, bool reset)
2223
2296
  }
2224
2297
  m_impl->m_keyValues.push_back(value);
2225
2298
  m_impl->m_nofilter = false;
2299
+ m_impl->m_seekByBookmarks = false;
2226
2300
  }
2227
2301
 
2228
2302
  void queryBase::addSeekKeyValuePtr(const void* value, ushort_td len,
@@ -2236,6 +2310,13 @@ void queryBase::addSeekKeyValuePtr(const void* value, ushort_td len,
2236
2310
  }
2237
2311
  m_impl->m_keyValuesPtr.push_back(keyValuePtr(value, len, typeStr));
2238
2312
  m_impl->m_nofilter = false;
2313
+ m_impl->m_seekByBookmarks = false;
2314
+ }
2315
+
2316
+ void queryBase::addSeekBookmark(bookmark_td& bm, ushort_td len, bool reset)
2317
+ {
2318
+ addSeekKeyValuePtr(&bm, len, KEYVALUE_PTR, reset);
2319
+ m_impl->m_seekByBookmarks = true;
2239
2320
  }
2240
2321
 
2241
2322
  void queryBase::clearSeekKeyValues()
@@ -2439,6 +2520,12 @@ queryBase& queryBase::stopAtLimit(bool v)
2439
2520
  return *this;
2440
2521
  }
2441
2522
 
2523
+ bool queryBase::isSeekByBookmarks() const
2524
+ {
2525
+ return m_impl->m_seekByBookmarks;
2526
+ }
2527
+
2528
+
2442
2529
  const std::vector<std::_tstring>& queryBase::getSelects() const
2443
2530
  {
2444
2531
  return m_impl->m_selects;
@@ -41,6 +41,17 @@ namespace client
41
41
  class database;
42
42
  class queryBase;
43
43
  class fields;
44
+ class table;
45
+ /** @endcond */
46
+
47
+ #if (defined(__BORLANDC__) && !defined(__clang__))
48
+ typedef void __stdcall(* recordCountFn)(table* tb, int count, bool& complate);
49
+ #else
50
+ /** @cond INTERNAL */
51
+ /** Callback function on a record was record count. */
52
+ typedef void(__STDCALL* recordCountFn)(table* tb, int count, bool& complate);
53
+ #endif
54
+
44
55
  #define null_str _T("")
45
56
 
46
57
  #pragma warning(disable : 4251)
@@ -120,7 +131,6 @@ protected:
120
131
  void* dataBak() const;
121
132
  void* reallocDataBuffer(uint_td v);
122
133
  int dataBufferLen() const;
123
- void setBookMarks(int StartId, void* Data, ushort_td Count);
124
134
  uint_td unPack(char* ptr, size_t size);
125
135
  uint_td pack(char* ptr, size_t size);
126
136
  keylen_td writeKeyData(); // orverride
@@ -147,7 +157,7 @@ protected:
147
157
 
148
158
  virtual void doInit(tabledef** def, short filenum, bool regularDir);
149
159
 
150
- virtual void onRecordCounting(size_t count, bool& complate){};
160
+ virtual void onRecordCounting(size_t count, bool& cancel);
151
161
 
152
162
  virtual void setNoUpdateTimeStamp(bool v){};
153
163
 
@@ -172,8 +182,10 @@ public:
172
182
  void* optionalData() const;
173
183
  void setOptionalData(void* v);
174
184
  bool myDateTimeValueByBtrv() const;
175
- int bookMarksCount() const;
176
- void moveBookmarksId(long Id);
185
+ void insertBookmarks(unsigned int start, void* data, ushort_td count);
186
+ int bookmarksCount() const;
187
+ void moveBookmarks(unsigned int index);
188
+ bookmark_td bookmarks(unsigned int index) const;
177
189
  void clearBuffer();
178
190
  unsigned int getRecordHash();
179
191
  void smartUpdate();
@@ -275,6 +287,8 @@ public:
275
287
  void keyValueDescription(_TCHAR* buf, int bufsize);
276
288
  short getCurProcFieldCount() const;
277
289
  short getCurProcFieldIndex(short index) const;
290
+ void setOnRecordCount(const recordCountFn v);
291
+ recordCountFn onRecordCount() const;
278
292
  client::fields& fields();
279
293
  };
280
294
 
@@ -328,6 +342,7 @@ public:
328
342
  void addLogic(const _TCHAR* combine, const _TCHAR* name,
329
343
  const _TCHAR* logic, const _TCHAR* value);
330
344
  void addSeekKeyValue(const _TCHAR* value, bool reset = false);
345
+ void addSeekBookmark(bookmark_td& bm, ushort_td len, bool reset = false);
331
346
  void addSeekKeyValuePtr(const void* value, ushort_td len, short typeStr,
332
347
  bool reset = false);
333
348
  void reserveSeekKeyValueSize(size_t v);
@@ -350,13 +365,13 @@ public:
350
365
  eOptimize getOptimize() const;
351
366
  bool isStopAtLimit() const;
352
367
  bool isBookmarkAlso() const;
368
+ bool isSeekByBookmarks() const;
353
369
  short selectCount() const;
354
370
  const _TCHAR* getSelect(short index) const;
355
371
  short whereTokens() const;
356
372
  const _TCHAR* getWhereToken(short index) const;
357
373
  void setWhereToken(short index, const _TCHAR* v);
358
374
  void reverseAliasName(const _TCHAR* alias, const _TCHAR* src);
359
-
360
375
  void release(); // don't virtual
361
376
  static queryBase* create();
362
377
  };