transactd 2.0.1 → 2.1.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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +6 -6
  3. data/README +16 -16
  4. data/README-JA +16 -16
  5. data/bin/common/tdclc_32_2_1.dll +0 -0
  6. data/bin/common/tdclc_64_2_1.dll +0 -0
  7. data/build/common/transactd_cl_common.cmake +0 -1
  8. data/build/common/transactd_common.cmake +28 -38
  9. data/build/swig/ruby/ruby.swg +36 -30
  10. data/build/swig/ruby/tdclrb_wrap.cpp +35016 -0
  11. data/build/swig/tdcl.i +217 -62
  12. data/build/tdclc/CMakeLists.txt +14 -26
  13. data/build/tdclc/libtdclcm.map +4 -0
  14. data/build/tdclc/tdclc.cbproj +1 -1
  15. data/build/tdclc/tdclc.rc +0 -0
  16. data/build/tdclcpp/CMakeLists.txt +7 -22
  17. data/build/tdclcpp/tdclcpp.rc +0 -0
  18. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  19. data/build/tdclrb/CMakeLists.txt +7 -49
  20. data/build/tdclrb/tdclrb.rc +62 -0
  21. data/source/bzs/db/blobBuffer.h +5 -0
  22. data/source/bzs/db/blobStructs.h +2 -0
  23. data/source/bzs/db/engine/mysql/IReadRecords.h +9 -0
  24. data/source/bzs/db/engine/mysql/database.cpp +391 -169
  25. data/source/bzs/db/engine/mysql/database.h +178 -40
  26. data/source/bzs/db/engine/mysql/dbManager.cpp +45 -3
  27. data/source/bzs/db/engine/mysql/dbManager.h +3 -39
  28. data/source/bzs/db/engine/mysql/errorMessage.cpp +11 -7
  29. data/source/bzs/db/engine/mysql/errorMessage.h +1 -1
  30. data/source/bzs/db/engine/mysql/mydebuglog.cpp +1 -2
  31. data/source/bzs/db/engine/mysql/mysqlInternal.h +8 -8
  32. data/source/bzs/db/engine/mysql/mysqlThd.cpp +11 -0
  33. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
  34. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +41 -6
  35. data/source/bzs/db/protocol/tdap/client/activeTable.h +177 -8
  36. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +141 -62
  37. data/source/bzs/db/protocol/tdap/client/client.cpp +39 -35
  38. data/source/bzs/db/protocol/tdap/client/client.h +52 -25
  39. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +17 -0
  40. data/source/bzs/db/protocol/tdap/client/connectionPool.h +1 -0
  41. data/source/bzs/db/protocol/tdap/client/database.cpp +5 -1
  42. data/source/bzs/db/protocol/tdap/client/database.h +1 -1
  43. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +49 -12
  44. data/source/bzs/db/protocol/tdap/client/databaseManager.h +42 -5
  45. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +4 -2
  46. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +71 -41
  47. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +49 -49
  48. data/source/bzs/db/protocol/tdap/client/field.cpp +22 -13
  49. data/source/bzs/db/protocol/tdap/client/field.h +7 -3
  50. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +1 -1
  51. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +0 -1
  52. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +1 -0
  53. data/source/bzs/db/protocol/tdap/client/fields.h +111 -24
  54. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +1 -1
  55. data/source/bzs/db/protocol/tdap/client/filter.h +687 -310
  56. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +12 -4
  57. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +1 -1
  58. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +190 -32
  59. data/source/bzs/db/protocol/tdap/client/memRecord.h +64 -22
  60. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +4 -4
  61. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -2
  62. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +6 -3
  63. data/source/bzs/db/protocol/tdap/client/nsTable.h +1 -1
  64. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +19 -8
  65. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +194 -87
  66. data/source/bzs/db/protocol/tdap/client/request.h +84 -26
  67. data/source/bzs/db/protocol/tdap/client/stringConverter.h +22 -12
  68. data/source/bzs/db/protocol/tdap/client/table.cpp +494 -286
  69. data/source/bzs/db/protocol/tdap/client/table.h +48 -5
  70. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +133 -87
  71. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +22 -22
  72. data/source/bzs/db/protocol/tdap/client/trdormapi.h +43 -18
  73. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +3 -3
  74. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +1 -0
  75. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +268 -74
  76. data/source/bzs/db/protocol/tdap/mysql/request.h +4 -4
  77. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +179 -43
  78. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +4 -4
  79. data/source/bzs/db/protocol/tdap/tdapRequest.h +15 -14
  80. data/source/bzs/db/protocol/tdap/tdapSchema.h +125 -90
  81. data/source/bzs/db/protocol/tdap/tdapcapi.h +46 -5
  82. data/source/bzs/db/transactd/appModule.h +1 -1
  83. data/source/bzs/db/transactd/connManager.cpp +2 -0
  84. data/source/bzs/db/transactd/transactd.cpp +1 -0
  85. data/source/bzs/env/compiler.h +10 -0
  86. data/source/bzs/env/mbcswchrLinux.cpp +42 -6
  87. data/source/bzs/env/mbcswchrLinux.h +40 -12
  88. data/source/bzs/example/queryData.cpp +33 -4
  89. data/source/bzs/netsvc/client/iconnection.h +107 -0
  90. data/source/bzs/netsvc/client/tcpClient.cpp +15 -1
  91. data/source/bzs/netsvc/client/tcpClient.h +96 -87
  92. data/source/bzs/netsvc/server/serverCpt.cpp +5 -6
  93. data/source/bzs/rtl/benchmark.cpp +2 -2
  94. data/source/bzs/rtl/stringBuffers.cpp +3 -3
  95. data/source/bzs/rtl/stringBuffers.h +2 -2
  96. data/source/bzs/test/tdclatl/bench_query_atl.js +92 -99
  97. data/source/bzs/test/tdclatl/test_query_atl.js +224 -115
  98. data/source/bzs/test/tdclphp/bench.php +126 -101
  99. data/source/bzs/test/tdclphp/transactd_Test.php +1122 -158
  100. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +12 -14
  101. data/source/bzs/test/tdclrb/transactd_spec.rb +1127 -142
  102. data/source/bzs/test/transactdBench/query_bench.cpp +32 -15
  103. data/source/bzs/test/transactdBench/scaling_bench.cpp +32 -7
  104. data/source/bzs/test/transactdBench/transactdBench.cpp +1 -1
  105. data/source/bzs/test/transactdBench/workerBase.h +46 -0
  106. data/source/bzs/test/transactdBench/workerMySQLImple.h +15 -7
  107. data/source/bzs/test/transactdBench/workerTransactdImple.h +10 -18
  108. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1487 -174
  109. data/source/global/ormsrcgen/main.cpp +2 -0
  110. data/source/global/tdclatl/Database.cpp +2 -2
  111. data/source/global/tdclatl/Database.h +1 -1
  112. data/source/global/tdclatl/FieldDefs.cpp +0 -3
  113. data/source/global/tdclatl/PooledDbManager.cpp +2 -2
  114. data/source/global/tdclatl/PooledDbManager.h +1 -1
  115. data/source/global/tdclatl/PreparedQuery.cpp +53 -0
  116. data/source/global/tdclatl/PreparedQuery.h +61 -0
  117. data/source/global/tdclatl/QueryBase.cpp +2 -1
  118. data/source/global/tdclatl/QueryBase.h +1 -1
  119. data/source/global/tdclatl/Record.cpp +3 -15
  120. data/source/global/tdclatl/Recordset.cpp +15 -10
  121. data/source/global/tdclatl/Recordset.h +3 -0
  122. data/source/global/tdclatl/Table.cpp +42 -7
  123. data/source/global/tdclatl/Table.h +3 -1
  124. data/source/global/tdclatl/activeTable.cpp +264 -76
  125. data/source/global/tdclatl/activeTable.h +12 -3
  126. data/source/global/tdclatl/tdclatl.idl +92 -10
  127. data/source/linux/charsetConvert.h +7 -7
  128. data/transactd.gemspec +14 -27
  129. metadata +18 -27
  130. data/bin/common/tdclc_32_2_0.dll +0 -0
  131. data/bin/common/tdclc_64_2_0.dll +0 -0
  132. data/build/swig/php/generate.cmake.in +0 -56
  133. data/build/swig/php/generate.cmd.in +0 -47
  134. data/build/swig/php/php.swg +0 -197
  135. data/build/swig/php/transactd.no_yield.php +0 -4494
  136. data/build/swig/php/transactd.no_yield.php.git.patch +0 -685
  137. data/build/swig/php/transactd.no_yield.php.patch +0 -685
  138. data/build/swig/php/transactd.yield.php +0 -4461
  139. data/build/swig/php/transactd.yield.php.git.patch +0 -652
  140. data/build/swig/php/transactd.yield.php.patch +0 -652
  141. data/build/swig/ruby/generate.cmake.in +0 -35
  142. data/build/swig/ruby/generate.cmd.in +0 -19
  143. data/build/tdclc/BUILDNUMBER.txt +0 -1
  144. data/build/tdclcpp/BUILDNUMBER.txt +0 -1
  145. data/build/tdclrb/BUILDNUMBER.txt +0 -1
  146. data/build/tdclrb/GEM_RELEASE_VERSION +0 -1
@@ -20,6 +20,7 @@
20
20
  ================================================================= */
21
21
 
22
22
  #include <bzs/db/protocol/tdap/tdapRequest.h>
23
+ #include <bzs/netsvc/client/iconnection.h>
23
24
 
24
25
  #ifdef USE_DATA_COMPRESS
25
26
  #include <bzs/rtl/lzss.h>
@@ -27,13 +28,6 @@
27
28
 
28
29
  namespace bzs
29
30
  {
30
- namespace netsvc
31
- {
32
- namespace client
33
- {
34
- class connection;
35
- }
36
- }
37
31
 
38
32
  namespace db
39
33
  {
@@ -52,47 +46,106 @@ namespace tdap
52
46
  namespace client
53
47
  {
54
48
 
55
- class request : public bzs::db::protocol::tdap::request
49
+ class request : public bzs::db::protocol::tdap::request,
50
+ public bzs::netsvc::client::idirectReadHandler
56
51
  {
57
52
  public:
58
53
  clientID* cid;
59
54
 
60
55
  request() : bzs::db::protocol::tdap::request(), cid(NULL){};
61
56
 
62
- inline void parse(const char* p, unsigned int segmentDataLen,
63
- unsigned short rows)
57
+ unsigned int onRead(unsigned int size, bzs::netsvc::client::connection* c) // orverride
64
58
  {
65
- p += sizeof(unsigned int);
66
- paramMask = *((ushort_td*)p);
59
+ unsigned int readlen = 0;
60
+ readlen += c->directRead(&paramMask, sizeof(uint_td)); // paramMask and result
61
+ if (P_MASK_POSBLK & paramMask)
62
+ readlen += c->directRead(pbk, TD_POSBLK_TRANSMIT_SIZE);
63
+
64
+ if (P_MASK_DATALEN & paramMask)
65
+ {
66
+ uint_td tmp;
67
+ readlen += c->directRead(&tmp, sizeof(uint_td));
68
+ if (*datalen < tmp)
69
+ {
70
+ result = STATUS_BUFFERTOOSMALL;
71
+ return readlen;
72
+ }
73
+ else
74
+ {
75
+ if (pbk->allocFunc && pbk->tb)
76
+ data = pbk->allocFunc(pbk->tb, tmp);
77
+ *datalen = tmp;
78
+ if (P_MASK_DATA & paramMask)
79
+ readlen += c->directRead(data, *datalen);
80
+ }
81
+ }
82
+
83
+ if (P_MASK_KEYBUF & paramMask)
84
+ {
85
+ keylen_td tmp;
86
+ readlen += c->directRead(&tmp, sizeof(keylen_td));
87
+ if (keylen < tmp)
88
+ {
89
+ result = STATUS_KEYBUFFERTOOSMALL;
90
+ return readlen;
91
+ }
92
+ memset(keybuf, 0, keylen);
93
+ keylen = tmp;
94
+ readlen += c->directRead(keybuf, keylen);
95
+ }
96
+ if (P_MASK_KEYNUM & paramMask)
97
+ readlen += c->directRead(&keyNum, sizeof(char_td));
98
+
99
+ if (paramMask & P_MASK_BLOBBODY)
100
+ {
101
+ blobHeader = (const bzs::db::blobHeader*)c->directReadRemain(size - readlen);
102
+ readlen = size;
103
+ if (blobHeader->rows)
104
+ blobHeader->resetCur();
105
+ }
106
+ else
107
+ blobHeader = NULL;
108
+ assert(readlen == size);
109
+ return readlen;
110
+ }
111
+
112
+ inline void parse(const char* p, bool ex/*, unsigned int segmentDataLen,
113
+ unsigned short rows*/)
114
+ {
115
+ p += sizeof(unsigned int); // 4 byte read length
116
+ paramMask = *((ushort_td*)p); // 2 byte paramMask
67
117
  p += sizeof(ushort_td);
68
118
 
69
- result = *((ushort_td*)p);
119
+ result = *((ushort_td*)p); // 2 byte result
70
120
  p += sizeof(ushort_td);
71
121
 
72
- if (P_MASK_POSBLK & paramMask)
122
+ if (P_MASK_POSBLK & paramMask) // 4 byte pbk
73
123
  {
74
- memcpy(pbk, p, POSBLK_SIZE);
75
- p += POSBLK_SIZE;
124
+ memcpy(pbk, p, TD_POSBLK_TRANSMIT_SIZE);
125
+ p += TD_POSBLK_TRANSMIT_SIZE;
76
126
  }
77
127
 
78
128
  if (P_MASK_DATALEN & paramMask)
79
129
  {
80
130
  uint_td tmp = *((uint_td*)p);
81
131
  if (*datalen < tmp)
132
+ {
82
133
  result = STATUS_BUFFERTOOSMALL;
134
+ return ;
135
+ }
83
136
  else
84
137
  *datalen = tmp;
85
138
  p += sizeof(uint_td);
86
139
  }
87
140
 
88
- if (P_MASK_FINALDATALEN & paramMask)
141
+ /*if (P_MASK_FINALDATALEN & paramMask)
89
142
  {
90
143
  memset(data, 0, *datalen);
91
144
  if (*datalen < segmentDataLen)
92
145
  result = STATUS_BUFFERTOOSMALL;
93
146
  else
94
147
  *datalen = segmentDataLen;
95
- }
148
+ }*/
96
149
  #ifdef USE_DATA_COMPRESS
97
150
  if (P_MASK_USELZSS & paramMask)
98
151
  {
@@ -104,15 +157,20 @@ public:
104
157
  }
105
158
  else
106
159
  #endif
107
- if (P_MASK_DATA & paramMask)
160
+ if (P_MASK_DATA & paramMask)
108
161
  {
162
+ if (ex)
163
+ {
164
+ if (pbk->allocFunc && pbk->tb)
165
+ data = pbk->allocFunc(pbk->tb, *datalen);
166
+ }
109
167
  memcpy(data, p, *datalen);
110
168
  p += *datalen;
111
- if (P_MASK_FINALDATALEN & paramMask)
169
+ /*if (P_MASK_FINALDATALEN & paramMask)
112
170
  {
113
171
  memcpy(data, &rows, 2);
114
172
  p += sizeof(unsigned int);
115
- }
173
+ }*/
116
174
  }
117
175
  if (P_MASK_KEYBUF & paramMask)
118
176
  {
@@ -133,11 +191,11 @@ public:
133
191
  p += sizeof(char_td);
134
192
  }
135
193
 
136
- if (P_MASK_FINALRET & paramMask)
194
+ /*if (P_MASK_FINALRET & paramMask)
137
195
  {
138
196
  result = *((ushort_td*)p);
139
197
  p += sizeof(ushort_td);
140
- }
198
+ }*/
141
199
 
142
200
  if (paramMask & P_MASK_BLOBBODY)
143
201
  {
@@ -189,8 +247,8 @@ public:
189
247
 
190
248
  if (P_MASK_POSBLK & paramMask)
191
249
  {
192
- memcpy(p, pbk, POSBLK_SIZE);
193
- p += POSBLK_SIZE;
250
+ memcpy(p, pbk, TD_POSBLK_TRANSMIT_SIZE);
251
+ p += TD_POSBLK_TRANSMIT_SIZE;
194
252
  }
195
253
 
196
254
  if (P_MASK_DATALEN & paramMask)
@@ -208,7 +266,7 @@ public:
208
266
  }
209
267
  else
210
268
  #endif
211
- if (P_MASK_EX_SENDLEN & paramMask)
269
+ if (P_MASK_EX_SENDLEN & paramMask)
212
270
  {
213
271
  unsigned int v = *((unsigned int*)data);
214
272
  v &= 0xFFFFFFF; // 28bit
@@ -665,22 +665,32 @@ template <typename T>
665
665
  const T* readBlob(char* ptr, ::bzs::rtl::stringBuffer* strBufs,
666
666
  const fielddef& fd, stringConverter* cv)
667
667
  {
668
+ int offset = fd.blobLenBytes();
669
+ size_t len = fd.blobDataLen((const uchar_td*)ptr);
670
+ T* result;
671
+ if (len)
672
+ {
673
+ char** pc = (char**)(ptr + offset);
668
674
 
669
- int offset = fd.len - 8;
670
- T* result = (T*)(ptr + offset);
671
- char** pc = (char**)(ptr + fd.blobLenBytes());
675
+ if (len)
676
+ {
677
+ size_t olen = len * 2 + 1;
678
+ result = strBufs->getPtr<T>(olen);
679
+ if ((typeid(T) != typeid(char)) ||
680
+ (cv->isNeedConvert() && (typeid(T) == typeid(char))))
681
+ len = cv->revert(result, olen, *pc, len);
682
+ else if (((T*)(*pc))[len] != 0x00)
683
+ memcpy(result, *pc, len);
684
+ else
685
+ result = (T*)*pc;
686
+ }
687
+ result[len] = 0x00;
672
688
 
673
- if ((typeid(T) != typeid(char)) ||
674
- (cv->isNeedConvert() && (typeid(T) == typeid(char))))
689
+ }else
675
690
  {
676
- size_t len = fd.blobDataLen((const uchar_td*)ptr);
677
- size_t olen = len * 2 + 1;
678
- result = strBufs->getPtr<T>(olen);
679
- len = cv->revert(result, olen, *pc, len);
680
- result[len] = 0x00;
691
+ result = strBufs->getPtr<T>(1);
692
+ result[0] = 0x00;
681
693
  }
682
- else
683
- result = (T*)*pc;
684
694
  return result;
685
695
  }
686
696
  #pragma warn .8004
@@ -23,9 +23,9 @@
23
23
  #include "filter.h"
24
24
  #include "database.h"
25
25
  #include "bulkInsert.h"
26
+ #include <bzs/db/protocol/tdap/tdapRequest.h>
26
27
  #include <bzs/rtl/strtrim.h>
27
28
  #include <bzs/db/protocol/tdap/myDateTime.cpp>
28
- #include <bzs/db/blobStructs.h>
29
29
  #include <bzs/rtl/stringBuffers.h>
30
30
  #include "stringConverter.h"
31
31
  #include <boost/timer.hpp>
@@ -63,19 +63,18 @@ struct tbimpl
63
63
 
64
64
  void* bookMarks;
65
65
  client::fields fields;
66
- filter* filterPtr;
66
+ pq_handle filterPtr;
67
67
  recordCache* rc;
68
68
  multiRecordAlocator* mraPtr;
69
69
  void* dataBak;
70
70
  void* smartUpDate;
71
71
  void* bfAtcPtr;
72
72
  void* optionalData;
73
+ uint_td dataBufferLen;
73
74
  int bookMarksMemSize;
74
75
  int maxBookMarkedCount;
75
76
  char keybuf[MAX_KEYLEN];
76
- char exNext;
77
77
  char keyNumIndex[128];
78
- short exSlideStat;
79
78
 
80
79
  struct
81
80
  {
@@ -85,10 +84,10 @@ struct tbimpl
85
84
  };
86
85
 
87
86
  tbimpl(table& tb)
88
- : bookMarks(NULL), fields(tb), filterPtr(NULL), rc(NULL), mraPtr(NULL),
87
+ : bookMarks(NULL), fields(tb), rc(NULL), mraPtr(NULL),
89
88
  dataBak(NULL), smartUpDate(NULL), bfAtcPtr(NULL), optionalData(NULL),
90
- bookMarksMemSize(0), maxBookMarkedCount(0), smartUpDateFlag(false),
91
- dataPacked(false)
89
+ dataBufferLen(0), bookMarksMemSize(0), maxBookMarkedCount(0),
90
+ smartUpDateFlag(false), dataPacked(false)
92
91
  {
93
92
  memset(&keyNumIndex[0], 0, 128);
94
93
  }
@@ -101,8 +100,6 @@ struct tbimpl
101
100
  free(smartUpDate);
102
101
  if (bookMarks)
103
102
  free(bookMarks);
104
-
105
- delete filterPtr;
106
103
  }
107
104
  };
108
105
 
@@ -121,7 +118,7 @@ unsigned int hash(const char* s, int len)
121
118
  class recordCache
122
119
  {
123
120
  table* m_tb;
124
- filter* m_pFilter;
121
+ filter* m_filter;
125
122
  unsigned int m_row;
126
123
  unsigned int m_len;
127
124
  unsigned int m_unpackLen;
@@ -141,7 +138,7 @@ public:
141
138
 
142
139
  inline void reset()
143
140
  {
144
- m_pFilter = NULL;
141
+ m_filter = NULL;
145
142
  m_row = 0;
146
143
  m_rowCount = 0;
147
144
  m_ptr = NULL;
@@ -152,7 +149,33 @@ public:
152
149
 
153
150
  inline void setMemblockType(int v) { m_memblockType = v; }
154
151
 
155
- inline void hasManyJoin(int rowCount, uchar_td* data)
152
+ inline void moveNextRow(int bookmarkSize)
153
+ {
154
+ m_ptr += m_len;
155
+ m_len = m_unpackLen = *((unsigned short*)m_ptr);
156
+ m_ptr += DATASIZE_BYTE;
157
+ if (bookmarkSize)
158
+ {
159
+ m_bookmark = *((bookmark_td*)(m_ptr));
160
+ m_ptr += bookmarkSize;
161
+ }
162
+ }
163
+
164
+ inline void moveBlobRow(int row)
165
+ {
166
+ // blob pointer is allready point to next row
167
+ if (m_hd)
168
+ {
169
+ while (row - m_hd->curRow)
170
+ {
171
+ for (int j = 0; j < m_hd->fieldCount; ++j)
172
+ m_hd->nextField = (blobField*)m_hd->nextField->next();
173
+ ++m_hd->curRow;
174
+ }
175
+ }
176
+ }
177
+
178
+ inline void hasManyJoinMra(int rowCount, uchar_td* data)
156
179
  {
157
180
  int rowOffset = 0;
158
181
  int row = 0; // zero start
@@ -186,122 +209,148 @@ public:
186
209
  m_tb->m_impl->mraPtr->duplicateRow(row + rowOffset, count);
187
210
  }
188
211
 
189
- inline void reset(filter* p, uchar_td* data, unsigned int totalSize,
212
+ inline void resetMra(filter* p, uchar_td* data, unsigned int totalSize,
190
213
  const blobHeader* hd)
191
214
  {
192
- m_pFilter = p;
193
- m_row = 0;
194
- m_rowCount = *((unsigned short*)data);
195
- m_ptr = data + DATASIZE_BYTE;
196
- m_len = m_unpackLen =
197
- *((unsigned short*)m_ptr); // Not include bookmark and size bytes.
198
- m_ptr += DATASIZE_BYTE;
199
- if (m_pFilter->bookmarkSize())
200
- {
201
- m_bookmark = *((bookmark_td*)(m_ptr));
202
- m_ptr += m_pFilter->bookmarkSize();
203
- }
204
- m_tmpPtr = data + totalSize;
205
- if (m_tb->m_impl->mraPtr)
215
+ reset(p, data, totalSize, hd);
216
+ if (m_rowCount)
206
217
  {
207
- if (m_pFilter->hasManyJoin())
208
- hasManyJoin(m_rowCount, data);
209
- size_t recordLen = m_pFilter->fieldSelected()
210
- ? m_pFilter->totalFieldLen()
211
- : m_tb->tableDef()->maxRecordLen;
212
- m_tb->m_impl->mraPtr->init(m_rowCount, recordLen, m_memblockType,
213
- m_tb);
218
+ multiRecordAlocator* mra = m_tb->m_impl->mraPtr;
219
+ unsigned char* bd = NULL; //blob data
220
+ if (m_filter->hasManyJoin())
221
+ hasManyJoinMra(m_rowCount, data);
222
+ size_t recordLen = m_filter->fieldSelected()
223
+ ? m_filter->totalFieldLen()
224
+ : m_tb->tableDef()->maxRecordLen;
225
+ mra->init(m_rowCount, recordLen, m_memblockType, m_tb);
226
+ if (hd)
227
+ bd = mra->allocBlobBlock(hd->dataSize);
228
+
229
+ // copy each row data
230
+ int bookmarkSize = m_filter->bookmarkSize();
231
+ const tabledef* td = m_tb->tableDef();
232
+ ushort_td fieldCount = m_filter->fieldCount();
233
+ m_tmpPtr = mra->ptr(m_row, mra_current_block);
234
+ int resultOffset = 0;
235
+
236
+ while (m_row < m_rowCount)
237
+ {
238
+ if ((m_len == 0) && m_filter->isSeeksMode() && fieldCount)
239
+ mra->setInvalidRecord(m_row, true);
240
+ else
241
+ {
242
+ if (m_filter->fieldSelected())
243
+ {
244
+ uchar_td* fieldPtr = m_ptr;
245
+ resultOffset = 0;
246
+ int blobFieldNum = 0;
247
+ for (int i = 0; i < fieldCount; i++)
248
+ {
249
+ const fielddef& fd =
250
+ td->fieldDefs[m_filter->selectFieldIndexes()[i]];
251
+ if (fd.isBlob())
252
+ {
253
+ bd = fd.setBlobFieldPointer(m_tmpPtr + resultOffset, m_hd, bd, blobFieldNum++);
254
+ fieldPtr += fd.len;
255
+ }
256
+ else
257
+ fieldPtr += fd.unPackCopy(m_tmpPtr + resultOffset, fieldPtr);
258
+ resultOffset += fd.len;
259
+ }
260
+ }
261
+ else if (m_tb->valiableFormatType())
262
+ {
263
+ memset(m_tmpPtr, 0, td->maxRecordLen);
264
+ memcpy(m_tmpPtr, m_ptr, m_len);
265
+ m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
266
+ m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
267
+ resultOffset = m_unpackLen;
268
+ }
269
+ else
270
+ {
271
+ memcpy(m_tmpPtr, m_ptr, m_len);
272
+ resultOffset = m_len;
273
+ }
274
+ }
275
+ ++m_row;
276
+ moveNextRow(bookmarkSize);
277
+ m_tmpPtr += resultOffset;
278
+ }
214
279
  }
215
- m_hd = const_cast<blobHeader*>(hd);
280
+ //prebuilt next ead operation
281
+ setMemblockType(mra_nextrows);
216
282
  }
217
283
 
218
- inline const uchar_td* moveRow(int count)
284
+ inline void reset(filter* p, uchar_td* data, unsigned int totalSize,
285
+ const blobHeader* hd)
219
286
  {
220
- // move row data address pointer in result buffer
221
- for (int i = 0; i < count; i++)
287
+ m_filter = p;
288
+ m_row = 0;
289
+ m_rowCount = *((unsigned short*)data);
290
+ if (m_rowCount)
222
291
  {
223
- m_ptr += m_len;
224
- m_len = m_unpackLen = *((unsigned short*)m_ptr);
292
+ m_ptr = data + DATASIZE_BYTE;
293
+ m_len = m_unpackLen =
294
+ *((unsigned short*)m_ptr); // Not include bookmark and size bytes.
295
+
225
296
  m_ptr += DATASIZE_BYTE;
226
- if (m_pFilter->bookmarkSize())
297
+ if (m_filter->bookmarkSize())
227
298
  {
228
299
  m_bookmark = *((bookmark_td*)(m_ptr));
229
- m_ptr += m_pFilter->bookmarkSize();
300
+ m_ptr += m_filter->bookmarkSize();
230
301
  }
302
+ m_tmpPtr = data + totalSize;
303
+ m_hd = const_cast<blobHeader*>(hd);
231
304
  }
232
- if (m_hd)
233
- {
234
- // blob pointer is allready point to next row
235
- while (m_row - m_hd->curRow)
236
- {
237
- for (int j = 0; j < m_hd->fieldCount; ++j)
238
- m_hd->nextField = (blobField*)m_hd->nextField->next();
239
- ++m_hd->curRow;
240
- }
241
- }
242
-
243
- multiRecordAlocator* mra = m_tb->m_impl->mraPtr;
305
+ }
244
306
 
307
+ inline const uchar_td* moveRow(int count)
308
+ {
309
+ // move row data address pointer in result buffer
310
+ int bookmarkSize = m_filter->bookmarkSize();
311
+ for (int i = 0; i < count; i++)
312
+ moveNextRow(bookmarkSize);
313
+ moveBlobRow(m_row);
314
+
245
315
  m_tb->m_fddefs->strBufs()->clear();
316
+ multiRecordAlocator* mra = m_tb->m_impl->mraPtr;
317
+ const tabledef* td = m_tb->tableDef();
318
+ ushort_td fieldCount = m_filter->fieldCount();
246
319
 
247
- if ((m_len == 0) && m_pFilter->isSeeksMode() && m_pFilter->fieldCount())
320
+ if ((m_len == 0) && m_filter->isSeeksMode() && fieldCount)
248
321
  {
249
- /*seek error*/
322
+
250
323
  m_seekMultiStat = STATUS_NOT_FOUND_TI;
251
- if (mra)
252
- {
253
- m_tmpPtr = mra->ptr(m_row, mra_current_block);
254
- mra->setInvalidRecord(m_row, true);
255
- }
256
- else
257
- memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
324
+ memset(m_tmpPtr, 0, td->maxRecordLen);
258
325
  return m_tmpPtr;
259
326
  }
260
327
  else
261
- m_seekMultiStat = 0;
262
-
263
- if (mra)
264
- m_tmpPtr = mra->ptr(m_row, mra_current_block);
265
-
266
- if (m_pFilter->fieldSelected())
267
328
  {
268
- int resultOffset = 0;
269
- uchar_td* fieldPtr = m_ptr;
270
- if (!mra)
271
- memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
272
- for (int i = 0; i < m_pFilter->fieldCount(); i++)
329
+ m_seekMultiStat = 0;
330
+ if (m_filter->fieldSelected())
273
331
  {
274
- const fielddef& fd =
275
- m_tb->tableDef()
276
- ->fieldDefs[m_pFilter->selectFieldIndexes()[i]];
277
- if (!mra)
332
+ int resultOffset = 0;
333
+ uchar_td* fieldPtr = m_ptr;
334
+ memset(m_tmpPtr, 0, td->maxRecordLen);
335
+ for (int i = 0; i < fieldCount; i++)
336
+ {
337
+ const fielddef& fd =
338
+ td->fieldDefs[m_filter->selectFieldIndexes()[i]];
278
339
  resultOffset = fd.pos;
279
- fieldPtr += fd.unPackCopy(m_tmpPtr + resultOffset, fieldPtr);
280
- if (mra)
281
- resultOffset += fd.len;
340
+ fieldPtr += fd.unPackCopy(m_tmpPtr + resultOffset, fieldPtr);
341
+ }
282
342
  }
283
- m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
284
- return m_tmpPtr;
285
- }
286
- else if (m_tb->valiableFormatType())
287
- {
288
- memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
289
- memcpy(m_tmpPtr, m_ptr, m_len);
290
- m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
291
- m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
292
- return m_tmpPtr;
293
- }
294
- else
295
- {
296
- if (mra)
343
+ else if (m_tb->valiableFormatType())
297
344
  {
345
+ memset(m_tmpPtr, 0, td->maxRecordLen);
298
346
  memcpy(m_tmpPtr, m_ptr, m_len);
299
- m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
300
- return m_tmpPtr;
347
+ m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
301
348
  }
302
349
  else
303
- m_tb->setBlobFieldPointer((char*)m_ptr, m_hd);
304
- return m_ptr;
350
+ m_tmpPtr = m_ptr;
351
+
352
+ m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
353
+ return m_tmpPtr;
305
354
  }
306
355
  }
307
356
 
@@ -343,6 +392,13 @@ table::table(nsdatabase* pbe) : nstable(pbe)
343
392
  m_pdata = NULL;
344
393
  m_keybuf = &m_impl->keybuf[0];
345
394
  m_keynum = 0;
395
+
396
+ if (isUseTransactd())
397
+ {
398
+ tdap::posblk* pbk = (tdap::posblk*)posblk();
399
+ pbk->tb = this;
400
+ pbk->allocFunc = DDBA;
401
+ }
346
402
  }
347
403
 
348
404
  table::~table()
@@ -352,6 +408,18 @@ table::~table()
352
408
  delete m_impl;
353
409
  }
354
410
 
411
+ void* __STDCALL table::DDBA(client::table* tb, uint_td size)
412
+ {
413
+ return tb->doDdba(size);
414
+ }
415
+
416
+ void* table::doDdba(uint_td size)
417
+ {
418
+ if (m_impl->filterPtr)
419
+ size += tableDef()->maxRecordLen;;
420
+ return reallocDataBuffer(size);
421
+ }
422
+
355
423
  void table::setMra(multiRecordAlocator* p)
356
424
  {
357
425
  m_impl->mraPtr = p;
@@ -365,7 +433,7 @@ multiRecordAlocator* table::mra() const
365
433
  uchar_td table::charset() const
366
434
  {
367
435
  return m_tableDef->charsetIndex;
368
- };
436
+ }
369
437
 
370
438
  bool table::trimPadChar() const
371
439
  {
@@ -380,22 +448,42 @@ void table::setTrimPadChar(bool v)
380
448
  bool table::usePadChar() const
381
449
  {
382
450
  return m_fddefs->usePadChar;
383
- };
451
+ }
384
452
 
385
453
  void table::setUsePadChar(bool v)
386
454
  {
387
455
  m_fddefs->usePadChar = v;
388
- };
456
+ }
389
457
 
390
458
  void* table::dataBak() const
391
459
  {
392
460
  return m_impl->dataBak;
393
- };
461
+ }
394
462
 
395
- void table::setDataBak(void* v)
463
+ void* table::reallocDataBuffer(uint_td v)
396
464
  {
397
- m_impl->dataBak = v;
398
- };
465
+ if ((m_impl->dataBak == NULL) || (m_impl->dataBufferLen < v))
466
+ {
467
+ v = v * 15 / 10; // 1.5f
468
+ if (m_impl->dataBak == NULL)
469
+ m_impl->dataBak = (void*)malloc(v);
470
+ else
471
+ m_impl->dataBak = (void*)realloc(m_impl->dataBak, v);
472
+ if (!m_impl->dataBak)
473
+ {
474
+ m_impl->dataBufferLen = 0;
475
+ m_stat = STATUS_CANT_ALLOC_MEMORY;
476
+ }else
477
+ m_impl->dataBufferLen = v;
478
+ }
479
+ setData(m_impl->dataBak);
480
+ return m_impl->dataBak;
481
+ }
482
+
483
+ int table::dataBufferLen() const
484
+ {
485
+ return m_impl->dataBufferLen;
486
+ }
399
487
 
400
488
  void* table::optionalData() const
401
489
  {
@@ -415,7 +503,7 @@ bool table::myDateTimeValueByBtrv() const
415
503
  bool table::logicalToString() const
416
504
  {
417
505
  return m_fddefs->logicalToString;
418
- };
506
+ }
419
507
 
420
508
  void table::setLogicalToString(bool v)
421
509
  {
@@ -480,10 +568,26 @@ inline short calcNextReadRecordCount(ushort_td curCount, int eTime)
480
568
  uint_td table::doRecordCount(bool estimate, bool fromCurrent)
481
569
  {
482
570
  uint_td result = 0;
571
+ client::filter* filter = m_impl->filterPtr.get();
483
572
 
484
- if (m_impl->filterPtr)
573
+
574
+ if (filter)
485
575
  {
486
- short_td op = (m_impl->filterPtr->direction() == findForword)
576
+ struct smartChangePreparedId
577
+ {
578
+ ushort_td m_id;
579
+ client::filter* m_filter;
580
+ smartChangePreparedId(client::filter* filter)
581
+ :m_filter(filter)
582
+ {
583
+ m_id = m_filter->preparedId();
584
+ m_filter->setServerPreparedId(0);
585
+ }
586
+
587
+ ~smartChangePreparedId(){ m_filter->setServerPreparedId(m_id); }
588
+ }changePreparedId(filter);
589
+
590
+ short_td op = (filter->direction() == findForword)
487
591
  ? TD_KEY_NEXT_MULTI
488
592
  : TD_KEY_PREV_MULTI;
489
593
 
@@ -495,10 +599,10 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
495
599
 
496
600
  bookmark_td bm = bookmark();
497
601
 
498
- ushort_td tmpRejectCount = m_impl->filterPtr->rejectCount();
499
- ushort_td tmpRecCount = m_impl->filterPtr->recordCount();
602
+ ushort_td tmpRejectCount = filter->rejectCount();
603
+ ushort_td tmpRecCount = filter->recordCount();
500
604
 
501
- m_impl->filterPtr->setIgnoreFields(true);
605
+ filter->setIgnoreFields(true);
502
606
  m_impl->maxBookMarkedCount = 0;
503
607
  if (fromCurrent)
504
608
  m_stat = curStat;
@@ -511,10 +615,10 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
511
615
  else if (op == TD_POS_PREV_MULTI)
512
616
  stepLast();
513
617
 
514
- m_impl->filterPtr->setMaxRows(recCountOnce);
618
+ filter->setMaxRows(recCountOnce);
515
619
  if (m_stat == 0)
516
620
  {
517
- m_impl->filterPtr->setPosTypeNext(false);
621
+ filter->setPosTypeNext(false);
518
622
  boost::timer t;
519
623
  btrvGetExtend(op);
520
624
  int eTime = (int)(t.elapsed() * 1000);
@@ -539,25 +643,25 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
539
643
  }
540
644
  }
541
645
  recCountOnce = calcNextReadRecordCount(recCountOnce, eTime);
542
- m_impl->filterPtr->setMaxRows(recCountOnce);
543
- result += *((ushort_td*)m_impl->dataBak);
646
+ filter->setMaxRows(recCountOnce);
647
+ result += *((ushort_td*)m_pdata/*m_impl->dataBak*/);
544
648
  setBookMarks(m_impl->maxBookMarkedCount + 1,
545
- (void*)((char*)m_impl->dataBak + 2),
546
- *((ushort_td*)m_impl->dataBak));
649
+ (void*)((char*)m_pdata/*m_impl->dataBak*/ + 2),
650
+ *((ushort_td*)m_pdata/*m_impl->dataBak*/));
547
651
  m_impl->maxBookMarkedCount = result;
548
652
  onRecordCounting(result, Complete);
549
653
  if (Complete)
550
654
  break;
551
655
  t.restart();
552
- m_impl->filterPtr->setPosTypeNext(true);
656
+ filter->setPosTypeNext(true);
553
657
  btrvGetExtend(op);
554
658
  eTime = (int)(t.elapsed() * 1000);
555
659
  }
556
660
  }
557
661
 
558
662
  short tmpStat = m_stat;
559
- m_impl->filterPtr->setIgnoreFields(false);
560
- m_impl->filterPtr->setMaxRows(tmpRecCount);
663
+ filter->setIgnoreFields(false);
664
+ filter->setMaxRows(tmpRecCount);
561
665
 
562
666
  if (bm)
563
667
  seekByBookmark(bm);
@@ -574,50 +678,80 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
574
678
 
575
679
  void table::btrvGetExtend(ushort_td op)
576
680
  {
681
+ client::filter* filter = m_impl->filterPtr.get();
682
+
683
+ // cacheing direction
684
+ if (!filter->setDirectionByOp(op))
685
+ {
686
+ m_stat = 1;
687
+ return ;
688
+ }
577
689
 
578
690
  if (op >= TD_KEY_GE_NEXT_MULTI)
579
691
  m_keylen = writeKeyData();
580
692
 
581
693
  m_pdata = m_impl->dataBak;
582
- if (!m_impl->filterPtr->writeBuffer())
694
+ if (!filter->writeBuffer())
583
695
  {
584
696
  m_stat = STATUS_WARKSPACE_TOO_SMALL;
585
697
  return;
586
698
  }
587
- m_datalen = m_impl->filterPtr->exDataBufLen();
588
-
589
- // cacheing direction
590
- if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI) ||
591
- (op == TD_POS_PREV_MULTI))
592
- m_impl->filterPtr->setDirection(findBackForword);
593
- else
594
- m_impl->filterPtr->setDirection(findForword);
699
+ m_datalen = filter->exDataBufLen();
595
700
 
596
701
  tdap(op);
597
702
  if (m_stat && (m_stat != STATUS_LIMMIT_OF_REJECT) &&
598
703
  (m_stat != STATUS_REACHED_FILTER_COND) && (m_stat != STATUS_EOF))
704
+ {
705
+ m_impl->filterPtr->setStat(m_stat);
599
706
  return;
707
+ }
600
708
  short stat = m_stat;
601
- if (!m_impl->filterPtr->isWriteComleted() &&
602
- (stat == STATUS_REACHED_FILTER_COND))
709
+ if (!filter->isWriteComleted() && (stat == STATUS_REACHED_FILTER_COND))
603
710
  stat = STATUS_LIMMIT_OF_REJECT;
604
711
 
605
- m_impl->rc->reset(m_impl->filterPtr, (uchar_td*)m_impl->dataBak, m_datalen,
606
- blobFieldUsed() ? getBlobHeader() : NULL);
607
-
608
- m_stat = stat;
609
- m_impl->exSlideStat = m_stat;
610
- // There is the right record.
611
- if (m_impl->rc->rowCount() && (!m_impl->exBookMarking))
712
+ const blobHeader* hd = blobFieldUsed() ? getBlobHeader() : NULL;
713
+ if (m_impl->mraPtr)
612
714
  {
613
- m_pdata = (void*)m_impl->rc->setRow(0);
614
- m_datalen = tableDef()->maxRecordLen;
715
+ m_impl->rc->resetMra(filter, (uchar_td*)m_pdata, m_datalen, hd);
716
+ m_stat = stat;
717
+ m_impl->filterPtr->setStat(stat);
718
+ }
719
+ else
720
+ {
721
+ m_impl->rc->reset(filter, (uchar_td*)m_pdata, m_datalen, hd);
722
+ m_stat = stat;
723
+ m_impl->filterPtr->setStat(stat);
724
+ // There is the right record.
725
+ if (m_impl->rc->rowCount() && (!m_impl->exBookMarking))
726
+ {
727
+ m_pdata = (void*)m_impl->rc->setRow(0);
728
+ m_datalen = tableDef()->maxRecordLen;
615
729
 
616
- m_stat = m_impl->rc->seekMultiStat();
730
+ m_stat = m_impl->rc->seekMultiStat();
731
+ }else if (!filter->isStatContinue())
732
+ m_stat = STATUS_EOF;
617
733
  }
618
- else if ((m_stat == STATUS_LIMMIT_OF_REJECT) &&
619
- (m_impl->filterPtr->rejectCount() >= 1))
620
- m_stat = STATUS_EOF;
734
+
735
+ }
736
+
737
+ bool table::recordsLoop(ushort_td& op)
738
+ {
739
+ client::filter* filter = m_impl->filterPtr.get();
740
+ filter->setPosTypeNext(true);
741
+ bool flag = (m_stat == STATUS_LIMMIT_OF_REJECT && (filter->rejectCount() == 0));
742
+ if (m_impl->mraPtr && !flag)
743
+ {
744
+ flag = m_impl->filterPtr->isStatContinue();
745
+ if (!flag)
746
+ m_stat = m_impl->filterPtr->translateStat();//finish
747
+ }
748
+ if (flag)
749
+ {
750
+ op = m_impl->filterPtr->isSeeksMode() ?
751
+ TD_KEY_SEEK_MULTI : (m_impl->filterPtr->direction() == table::findForword) ?
752
+ TD_KEY_NEXT_MULTI : TD_KEY_PREV_MULTI;
753
+ }
754
+ return flag;
621
755
  }
622
756
 
623
757
  void table::getRecords(ushort_td op)
@@ -625,10 +759,8 @@ void table::getRecords(ushort_td op)
625
759
  do
626
760
  {
627
761
  btrvGetExtend(op);
628
- m_impl->filterPtr->setPosTypeNext(true);
762
+ }while (recordsLoop(op));
629
763
 
630
- } while (m_stat == STATUS_LIMMIT_OF_REJECT &&
631
- (m_impl->filterPtr->rejectCount() == 0));
632
764
  if ((m_stat == STATUS_REACHED_FILTER_COND) ||
633
765
  (m_stat == STATUS_LIMMIT_OF_REJECT))
634
766
  m_stat = STATUS_EOF;
@@ -701,7 +833,7 @@ void table::btrvSeekMulti()
701
833
  // 100% need allocate each row
702
834
  m_impl->mraPtr->init(1, recordLen, type, this);
703
835
  type = mra_nextrows;
704
- seeks[i].writeBuffer((uchar_td*)m_impl->keybuf, false, true, transactd);
836
+ seeks[i].writeBuffer((uchar_td*)m_impl->keybuf, true, transactd);
705
837
  if (hasManyJoin)
706
838
  {
707
839
  tdap((ushort_td)(TD_KEY_OR_AFTER));
@@ -739,6 +871,92 @@ void table::btrvSeekMulti()
739
871
  m_stat = STATUS_EOF;
740
872
  }
741
873
 
874
+ void table::doFind(ushort_td op, bool notIncCurrent)
875
+ {
876
+ /*
877
+ First, read from cache.
878
+ If whole row readed from cache then select operation by m_impl->filterPtr->stat()
879
+
880
+ */
881
+ m_stat = 0;
882
+ int row = m_impl->rc->row() + 1;
883
+
884
+ if (m_impl->rc->withinCache(row) && (!m_impl->exBookMarking))
885
+ { /* read from cache */
886
+
887
+ /*Is direction same */
888
+ if (!m_impl->filterPtr->checkFindDirection(op))
889
+ {
890
+ m_stat = 1;
891
+ return;
892
+ }
893
+ m_pdata = (void*)m_impl->rc->setRow(row);
894
+ m_stat = m_impl->rc->seekMultiStat();
895
+
896
+ /*If seek multi error, set keyvalue for keyValueDescription*/
897
+ if (m_stat != 0)
898
+ setSeekValueField(row);
899
+
900
+ // m_datalen = m_impl->rc->len();
901
+ m_datalen = tableDef()->maxRecordLen;
902
+ }
903
+ else if (m_impl->rc->isEndOfRow(row))
904
+ {
905
+ /* whole row readed */
906
+ /*Is direction same */
907
+ if (!m_impl->filterPtr->checkFindDirection(op))
908
+ {
909
+ m_stat = 1;
910
+ return;
911
+ }
912
+ if (m_impl->filterPtr->isStatContinue())
913
+ {
914
+ //continue reading
915
+ m_impl->rc->setMemblockType(mra_nextrows);
916
+ getRecords(op);
917
+ }else
918
+ {
919
+ //finish
920
+ m_stat = m_impl->filterPtr->translateStat();
921
+ m_impl->filterPtr->setStat(0);
922
+ }
923
+ }
924
+ else
925
+ {
926
+ //reading
927
+ m_impl->filterPtr->setPosTypeNext(notIncCurrent);
928
+ getRecords(op);
929
+ }
930
+ }
931
+
932
+ bool table::doPrepare()
933
+ {
934
+ m_stat = 0;
935
+ if (!m_impl->filterPtr)
936
+ {
937
+ m_stat = STATUS_FILTERSTRING_ERROR;
938
+ return false;
939
+ }
940
+
941
+ m_pdata = m_impl->dataBak;
942
+ m_impl->filterPtr->setPreparingMode(true);
943
+ m_impl->filterPtr->setPosTypeNext(true);
944
+ if (!m_impl->filterPtr->writeBuffer())
945
+ {
946
+ m_stat = STATUS_WARKSPACE_TOO_SMALL;
947
+ m_impl->filterPtr->setPreparingMode(false);
948
+ return false;
949
+ }
950
+ m_datalen = m_impl->filterPtr->exDataBufLen();
951
+
952
+ tdap((ushort_td)(TD_FILTER_PREPARE));
953
+ m_impl->filterPtr->setPreparingMode(false);
954
+ if (m_stat != STATUS_SUCCESS)
955
+ return false;
956
+ m_impl->filterPtr->setServerPreparedId(*((ushort_td*)m_pdata));
957
+ return true;
958
+ }
959
+
742
960
  void table::find(eFindType type)
743
961
  {
744
962
  if (!m_impl->filterPtr)
@@ -795,8 +1013,6 @@ void table::findFirst()
795
1013
  {
796
1014
  if (m_impl->filterPtr)
797
1015
  {
798
-
799
- m_impl->exNext = 1;
800
1016
  m_impl->filterPtr->setPosTypeNext(false);
801
1017
  getRecords(TD_KEY_NEXT_MULTI);
802
1018
  }
@@ -810,90 +1026,12 @@ void table::findLast()
810
1026
  {
811
1027
  if (m_impl->filterPtr)
812
1028
  {
813
-
814
- m_impl->exNext = -1;
815
1029
  m_impl->filterPtr->setPosTypeNext(false);
816
1030
  getRecords(TD_KEY_PREV_MULTI);
817
1031
  }
818
1032
  }
819
1033
  }
820
1034
 
821
- bool table::checkFindDirection(ushort_td op)
822
- {
823
- bool ret;
824
- if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI))
825
- ret = (m_impl->filterPtr->direction() == findBackForword);
826
- else
827
- ret = (m_impl->filterPtr->direction() == findForword);
828
- if (!ret)
829
- {
830
- assert(0);
831
- m_stat = 1;
832
- }
833
- return ret;
834
- }
835
-
836
- void table::doFind(ushort_td op, bool notIncCurrent)
837
- {
838
- /*
839
- First, read from cache.
840
- If whole row readed from cache then select operation by m_impl->exSlideStat
841
-
842
- */
843
- m_stat = 0;
844
- int row = m_impl->rc->row() + 1;
845
-
846
- if (m_impl->rc->withinCache(row) && (!m_impl->exBookMarking))
847
- { /* read from cache */
848
-
849
- /*Is direction same */
850
- if (!checkFindDirection(op))
851
- return;
852
-
853
- m_pdata = (void*)m_impl->rc->setRow(row);
854
- m_stat = m_impl->rc->seekMultiStat();
855
-
856
- /*set keyvalue for keyValueDescription*/
857
- if (m_stat != 0)
858
- setSeekValueField(row);
859
-
860
- // m_datalen = m_impl->rc->len();
861
- m_datalen = tableDef()->maxRecordLen;
862
- }
863
- else if (m_impl->rc->isEndOfRow(row))
864
- {
865
- /* whole row readed */
866
- /*Is direction same */
867
- if (!checkFindDirection(op))
868
- return;
869
- /* A special situation that if rejectCount() == 0 and status =
870
- STATUS_LIMMIT_OF_REJECT
871
- then it continues . */
872
- if ((m_impl->exSlideStat == 0) ||
873
- ((m_impl->exSlideStat == STATUS_LIMMIT_OF_REJECT) &&
874
- (m_impl->filterPtr->rejectCount() == 0)))
875
- {
876
- m_impl->rc->setMemblockType(mra_nextrows);
877
- getRecords(op);
878
- return;
879
- }
880
- if ((m_impl->exSlideStat == STATUS_LIMMIT_OF_REJECT) ||
881
- (m_impl->exSlideStat == STATUS_REACHED_FILTER_COND))
882
- m_stat = STATUS_EOF;
883
- else
884
- m_stat = m_impl->exSlideStat;
885
- m_impl->exSlideStat = 0;
886
- }
887
- else
888
- {
889
- m_impl->exNext =
890
- ((op == TD_KEY_NEXT_MULTI) || (op == TD_KEY_GE_NEXT_MULTI)) ? 1
891
- : -1;
892
- m_impl->filterPtr->setPosTypeNext(notIncCurrent);
893
- getRecords(op);
894
- }
895
- }
896
-
897
1035
  void table::findNext(bool notIncCurrent)
898
1036
  {
899
1037
 
@@ -915,47 +1053,60 @@ void table::findPrev(bool notIncCurrent)
915
1053
  seekPrev();
916
1054
  }
917
1055
 
918
- void table::setQuery(const queryBase* query)
1056
+ void table::setPrepare(const pq_handle stmt)
1057
+ {
1058
+ m_stat = 0;
1059
+ if (!stmt)
1060
+ {
1061
+ m_stat = STATUS_FILTERSTRING_ERROR;
1062
+ return;
1063
+ }
1064
+ m_impl->rc->reset();
1065
+ m_impl->exBookMarking = false;
1066
+ m_impl->maxBookMarkedCount = 0;
1067
+ if (m_impl->filterPtr != stmt)
1068
+ m_impl->filterPtr = stmt;
1069
+ }
1070
+
1071
+ pq_handle table::setQuery(const queryBase* query, bool serverPrepare)
919
1072
  {
920
1073
 
921
1074
  m_stat = 0;
922
- m_pdata = m_impl->dataBak;
923
1075
  m_impl->rc->reset();
924
1076
  m_impl->exBookMarking = false;
925
- m_impl->exSlideStat = 0;
926
- m_impl->exNext = 0;
1077
+ m_impl->maxBookMarkedCount = 0;
1078
+ m_impl->filterPtr.reset();
927
1079
  if (query == NULL)
928
- {
929
- m_impl->maxBookMarkedCount = 0;
930
- delete m_impl->filterPtr;
931
- m_impl->filterPtr = NULL;
932
- return;
933
- }
934
- if (m_impl->filterPtr)
935
- m_impl->filterPtr->init(this);
936
- else
937
- m_impl->filterPtr = new filter(this);
938
- if (m_impl->filterPtr == NULL)
1080
+ return m_impl->filterPtr;
1081
+
1082
+ if (!m_impl->filterPtr)
1083
+ m_impl->filterPtr.reset(filter::create(this), filter::release);
1084
+
1085
+ if (!m_impl->filterPtr)
939
1086
  {
940
1087
  m_stat = STATUS_CANT_ALLOC_MEMORY;
941
- return;
1088
+ return m_impl->filterPtr;
942
1089
  }
943
- bool ret = false;
1090
+
944
1091
  try
945
1092
  {
946
- ret = m_impl->filterPtr->setQuery(query);
1093
+ bool ret = m_impl->filterPtr->setQuery(query);
1094
+ if (!ret)
1095
+ m_stat = STATUS_FILTERSTRING_ERROR;
1096
+ else
1097
+ {
1098
+ if (serverPrepare && isUseTransactd())
1099
+ ret = doPrepare();
1100
+ }
1101
+ if (!ret)
1102
+ m_impl->filterPtr.reset();
947
1103
  }
948
1104
  catch (...)
949
- {
950
- }
951
-
952
- if (!ret)
953
1105
  {
954
1106
  m_stat = STATUS_FILTERSTRING_ERROR;
955
- delete m_impl->filterPtr;
956
- m_impl->filterPtr = NULL;
957
- return;
1107
+ m_impl->filterPtr.reset();
958
1108
  }
1109
+ return m_impl->filterPtr;
959
1110
  }
960
1111
 
961
1112
  void table::setFilter(const _TCHAR* str, ushort_td RejectCount,
@@ -1030,10 +1181,10 @@ void table::doCreateIndex(bool SpecifyKeyNum)
1030
1181
  void table::smartUpdate()
1031
1182
  {
1032
1183
  if (!m_impl->smartUpDate)
1033
- m_impl->smartUpDate = malloc(m_buflen);
1184
+ m_impl->smartUpDate = malloc(m_tableDef->maxRecordLen);
1034
1185
  if (m_impl->smartUpDate)
1035
1186
  {
1036
- memcpy(m_impl->smartUpDate, data(), m_buflen);
1187
+ memcpy(m_impl->smartUpDate, data(), m_tableDef->maxRecordLen);
1037
1188
  m_impl->smartUpDateFlag = true;
1038
1189
  }
1039
1190
  else
@@ -1077,7 +1228,7 @@ bool table::onUpdateCheck(eUpdateType type)
1077
1228
  else if (m_impl->smartUpDateFlag)
1078
1229
  {
1079
1230
  m_stat = 0;
1080
- if (memcmp(m_impl->smartUpDate, data(), m_buflen) == 0)
1231
+ if (memcmp(m_impl->smartUpDate, data(), m_tableDef->maxRecordLen) == 0)
1081
1232
  {
1082
1233
  m_impl->smartUpDateFlag = false;
1083
1234
  return false;
@@ -1140,9 +1291,7 @@ void* table::attachBuffer(void* NewPtr, bool unpack, size_t size)
1140
1291
  m_impl->bfAtcPtr = m_pdata;
1141
1292
  oldptr = m_pdata;
1142
1293
  m_pdata = NewPtr;
1143
- ushort_td len = recordLength();
1144
- if (len < m_tableDef->maxRecordLen)
1145
- len = m_tableDef->maxRecordLen;
1294
+ ushort_td len = m_tableDef->maxRecordLen;
1146
1295
  if (unpack)
1147
1296
  len = unPack((char*)m_pdata, size);
1148
1297
  m_datalen = len;
@@ -1165,13 +1314,8 @@ void table::doInit(tabledef* Def, short fnum, bool /*regularDir*/)
1165
1314
  {
1166
1315
  m_tableDef = Def;
1167
1316
  m_fddefs->addAllFileds(m_tableDef);
1168
- ushort_td len;
1169
-
1170
1317
  m_fddefs->cv()->setCodePage(mysql::codePage(m_tableDef->charsetIndex));
1171
-
1172
- if ((len = recordLength()) < m_tableDef->maxRecordLen)
1173
- len = m_tableDef->maxRecordLen;
1174
-
1318
+ ushort_td len = m_tableDef->maxRecordLen;
1175
1319
  if (len == 0)
1176
1320
  {
1177
1321
  m_stat = STATUS_INVALID_RECLEN;
@@ -1185,19 +1329,7 @@ void table::doInit(tabledef* Def, short fnum, bool /*regularDir*/)
1185
1329
  else
1186
1330
  m_impl->keyNumIndex[i] = (char)i;
1187
1331
  }
1188
- if (m_impl->dataBak)
1189
- free(m_impl->dataBak);
1190
- m_impl->dataBak = (void*)malloc(len);
1191
-
1192
- if (m_impl->dataBak == NULL)
1193
- {
1194
- if (m_impl->dataBak)
1195
- free(m_impl->dataBak);
1196
- m_impl->dataBak = NULL;
1197
- m_stat = STATUS_CANT_ALLOC_MEMORY;
1198
- return;
1199
- }
1200
- m_pdata = m_impl->dataBak;
1332
+ reallocDataBuffer(len);
1201
1333
  m_buflen = len;
1202
1334
  m_datalen = len;
1203
1335
  setTableid(fnum);
@@ -1268,7 +1400,7 @@ uint_td table::doGetWriteImageLen()
1268
1400
  {
1269
1401
  if (!blobFieldUsed() && !valiableFormatType() &&
1270
1402
  (m_tableDef->flags.bit0 == false))
1271
- return m_buflen;
1403
+ return m_tableDef->maxRecordLen;
1272
1404
  // Make blob pointer list
1273
1405
  if (blobFieldUsed())
1274
1406
  {
@@ -1289,7 +1421,7 @@ uint_td table::doGetWriteImageLen()
1289
1421
  addSendBlob(NULL);
1290
1422
 
1291
1423
  if (valiableFormatType())
1292
- return pack((char*)m_pdata, m_buflen);
1424
+ return pack((char*)m_pdata, m_tableDef->maxRecordLen);
1293
1425
  else
1294
1426
  {
1295
1427
  fielddef* fd = &m_tableDef->fieldDefs[m_tableDef->fieldCount - 1];
@@ -1325,7 +1457,7 @@ uint_td table::unPack(char* ptr, size_t size)
1325
1457
  {
1326
1458
  char* pos = ptr;
1327
1459
  const char* end = pos + size;
1328
- const char* max = pos + m_buflen;
1460
+ const char* max = pos + m_tableDef->maxRecordLen;
1329
1461
  int movelen;
1330
1462
  for (int i = 0; i < m_tableDef->fieldCount; i++)
1331
1463
  {
@@ -1442,8 +1574,8 @@ void table::onReadAfter()
1442
1574
  const blobHeader* hd = getBlobHeader();
1443
1575
  setBlobFieldPointer((char*)m_pdata, hd);
1444
1576
  }
1445
- if (m_buflen - m_datalen > 0)
1446
- memset((char*)m_pdata + m_datalen, 0, m_buflen - m_datalen);
1577
+ if (m_tableDef->maxRecordLen - m_datalen > 0)
1578
+ memset((char*)m_pdata + m_datalen, 0, m_tableDef->maxRecordLen - m_datalen);
1447
1579
  }
1448
1580
 
1449
1581
  short table::fieldNumByName(const _TCHAR* name)
@@ -2135,7 +2267,9 @@ queryBase& queryBase::direction(table::eFindType v)
2135
2267
 
2136
2268
  queryBase& queryBase::all()
2137
2269
  {
2138
- reset();
2270
+ m_impl->m_selects.clear();
2271
+ m_impl->m_wheres.clear();
2272
+ m_impl->m_keyValues.clear();
2139
2273
  m_impl->m_nofilter = true;
2140
2274
  return *this;
2141
2275
  }
@@ -2233,7 +2367,7 @@ int queryBase::getLimit() const
2233
2367
  bool queryBase::isAll() const
2234
2368
  {
2235
2369
  return m_impl->m_nofilter;
2236
- };
2370
+ }
2237
2371
 
2238
2372
  const std::vector<std::_tstring>& queryBase::getSelects() const
2239
2373
  {
@@ -2314,6 +2448,80 @@ queryBase* queryBase::create()
2314
2448
  return new queryBase();
2315
2449
  }
2316
2450
 
2451
+ int makeSupplyValues(const _TCHAR* values[], int size,
2452
+ const _TCHAR* value, const _TCHAR* value1,
2453
+ const _TCHAR* value2, const _TCHAR* value3,
2454
+ const _TCHAR* value4, const _TCHAR* value5,
2455
+ const _TCHAR* value6, const _TCHAR* value7,
2456
+ const _TCHAR* value8, const _TCHAR* value9,
2457
+ const _TCHAR* value10)
2458
+ {
2459
+ if (size == 0) return 0;
2460
+ memset(values, sizeof(_TCHAR*), size);
2461
+ values[0] = value;
2462
+ if (size < 2 || !value1) return 1;
2463
+ values[1] = value1;
2464
+ if (size < 3 || !value2) return 2;
2465
+ values[2] = value2;
2466
+ if (size < 4 || !value3) return 3;
2467
+ values[3] = value3;
2468
+ if (size < 5 || !value4) return 4;
2469
+ values[4] = value4;
2470
+ if (size < 6 || !value5) return 5;
2471
+ values[5] = value5;
2472
+ if (size < 7 || !value6) return 6;
2473
+ values[6] = value6;
2474
+ if (size < 8 || !value7) return 7;
2475
+ values[7] = value7;
2476
+ if (size < 9 || !value8) return 8;
2477
+ values[8] = value8;
2478
+ if (size < 10 || !value9) return 9;
2479
+ values[9] = value9;
2480
+ if (size < 11 || !value10) return 10;
2481
+ values[10] = value10;
2482
+ return 11;
2483
+ }
2484
+
2485
+ bool supplyValues(pq_handle& filter, const _TCHAR* values[], int size)
2486
+ {
2487
+ return filter->supplyValues(values, size);
2488
+ }
2489
+
2490
+ bool supplyValue(pq_handle& filter, int index, const _TCHAR* v)
2491
+ {
2492
+ return filter->supplyValue(index, v);
2493
+ }
2494
+
2495
+ bool supplyValue(pq_handle& filter, int index, short v)
2496
+ {
2497
+ return filter->supplyValue(index, v);
2498
+ }
2499
+
2500
+ bool supplyValue(pq_handle& filter, int index, int v)
2501
+ {
2502
+ return filter->supplyValue(index, v);
2503
+ }
2504
+
2505
+ bool supplyValue(pq_handle& filter, int index, __int64 v)
2506
+ {
2507
+ return filter->supplyValue(index, v);
2508
+ }
2509
+
2510
+ bool supplyValue(pq_handle& filter, int index, float v)
2511
+ {
2512
+ return filter->supplyValue(index, v);
2513
+ }
2514
+
2515
+ bool supplyValue(pq_handle& filter, int index, double v)
2516
+ {
2517
+ return filter->supplyValue(index, v);
2518
+ }
2519
+ /*
2520
+ bool supplyInValues(pq_handle& filter, const _TCHAR* values[], size_t size, int segments)
2521
+ {
2522
+ return filter->supplySeekValues(values, size, segments);
2523
+ }*/
2524
+
2317
2525
  } // namespace client
2318
2526
  } // namespace tdap
2319
2527
  } // namespace protocol