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
@@ -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
  };