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
@@ -105,7 +105,7 @@ void fileDDF::createTable(const _TCHAR* fullpath)
105
105
  {
106
106
  fileSpec* fs;
107
107
  fs = (fileSpec*)malloc(512);
108
- memset(fs, 512, 0x00);
108
+ memset(fs, 0x00, 512);
109
109
  fs->recLen = 97;
110
110
  fs->pageSize = 4096;
111
111
  fs->indexCount = 2;
@@ -36,22 +36,10 @@ namespace tdap
36
36
  namespace client
37
37
  {
38
38
 
39
- #define BOOKMARK_ALLOC_SIZE 40960
39
+
40
40
  #define BOOKMARK_SIZE 4
41
41
  #define DATASIZE_BYTE 2
42
42
 
43
- #define BTRV_MAX_DATA_SIZE 57000
44
- #define TDAP_MAX_DATA_SIZE 6291456 // 3Mbyte
45
-
46
- inline ushort_td varlenForFilter(const fielddef& fd)
47
- {
48
- if (((fd.type >= ft_myvarchar) && (fd.type <= ft_mywvarbinary)) ||
49
- fd.type == ft_lstring)
50
- return fd.len < 256 ? 1 : 2;
51
- else if ((fd.type == ft_myblob) || (fd.type == ft_mytext))
52
- return fd.len - 8;
53
- return 0;
54
- }
55
43
 
56
44
  /** Length of compare
57
45
  * if part of string or zstring then return strlen.
@@ -70,7 +58,7 @@ inline uint_td compDataLen(const fielddef& fd, const uchar_td* ptr, bool part)
70
58
  return length;
71
59
  }
72
60
 
73
- bool verType(uchar_td type)
61
+ inline bool verType(uchar_td type)
74
62
  {
75
63
  if (((type >= ft_myvarchar) && (type <= ft_mywvarbinary)) ||
76
64
  type == ft_lstring)
@@ -81,6 +69,93 @@ bool verType(uchar_td type)
81
69
  #pragma pack(push, 1)
82
70
  pragma_pack1;
83
71
 
72
+ /* Structure description of a filter data buffer
73
+
74
+ Normal Mode
75
+ =============================================================
76
+ -----------------------------------
77
+ header
78
+ -----------------------------------
79
+ --- P.SQL ---
80
+ len 2byte total of databaffer
81
+ type 2byte "EG" or "UC"(Include Current record)
82
+ --- or (Transatcd) ---
83
+ ilen int:28 total of databaffer
84
+ itype int:4 See define FILTER_CURRENT_TYPE_INC
85
+ --- end or ---
86
+ rejectCount 2byte reject count
87
+ --- or (sending supply value to server) ---
88
+ preparedId 2byte preparedId
89
+ --- end or ---
90
+ logicalCount 2byte logical count
91
+ -----------------------------------
92
+ filter
93
+ -----------------------------------
94
+ --- begin repeat ---
95
+ type 1byte data type
96
+ len 2byte field length (compare value length)
97
+ pos 2byte field position (zero origin)
98
+ logType 1byte compare type (=,>,<,<>,>=,<=)
99
+ + 16 var type compare whole length
100
+ + 32 compare by asc
101
+ + 64 copare with other field
102
+ + 128 case insensitive
103
+ opr 1byte next type
104
+ 0 end
105
+ 1 and
106
+ 2 or
107
+ +32 prepare placeholder (Only transactd)
108
+ data 2 or n field position (if compare type +64) or comapre value
109
+ --- end repeat ---
110
+ -----------------------------------
111
+ result
112
+ -----------------------------------
113
+ maxRows 2byte max record count
114
+ fieldCount 2byte field count of a record
115
+ --- begin repeat ---
116
+ len 2byte field length
117
+ pos 2byte field position
118
+ --- end repeat ---
119
+ -----------------------------------
120
+
121
+ Seeks mode
122
+ =============================================================
123
+ -----------------------------------
124
+ header
125
+ -----------------------------------
126
+ same as normal
127
+ -----------------------------------
128
+ seek values
129
+ -----------------------------------
130
+ --- begin repeat (key data of one record)---
131
+ data 2byte length of key data (multi segments)
132
+ len n key data
133
+ --- end repeat ---
134
+ -----------------------------------
135
+ result
136
+ -----------------------------------
137
+ same as normal
138
+
139
+ Prepare execute mode
140
+ =============================================================
141
+ -----------------------------------
142
+ header
143
+ -----------------------------------
144
+ itype |= FILTER_TYPE_SUPPLYVALUE
145
+ Onother is same as normal.
146
+ -----------------------------------
147
+ supply values
148
+ -----------------------------------
149
+ --- begin repeat ---
150
+ 2byte length of value
151
+ n value
152
+ --- end repeat ---
153
+ -----------------------------------
154
+ result
155
+ -----------------------------------
156
+ same as normal
157
+ */
158
+
84
159
  struct resultField
85
160
  {
86
161
  unsigned short len;
@@ -98,13 +173,15 @@ struct resultField
98
173
  }
99
174
  return -1;
100
175
  }
101
- unsigned char* writeBuffer(unsigned char* p, bool estimate)
176
+
177
+ unsigned char* writeBuffer(unsigned char* p)
102
178
  {
103
179
  int n = sizeof(resultField);
104
- if (!estimate)
105
- memcpy(p, this, n);
180
+ memcpy(p, this, n);
106
181
  return p + n;
107
182
  }
183
+
184
+ int size() const { return sizeof(resultField);}
108
185
  };
109
186
 
110
187
  struct resultDef
@@ -117,13 +194,15 @@ struct resultDef
117
194
  }
118
195
  unsigned short maxRows;
119
196
  unsigned short fieldCount;
120
- unsigned char* writeBuffer(unsigned char* p, bool estimate)
197
+ unsigned char* writeBuffer(unsigned char* p)
121
198
  {
122
199
  int n = sizeof(resultDef);
123
- if (!estimate)
124
- memcpy(p, this, n);
200
+ memcpy(p, this, n);
125
201
  return p + n;
126
202
  }
203
+
204
+ int size() const { return sizeof(resultDef); }
205
+
127
206
  friend class filter;
128
207
  };
129
208
 
@@ -133,8 +212,6 @@ struct seek
133
212
  unsigned short len;
134
213
 
135
214
  public:
136
- size_t getLength() { return sizeof(len) + len; }
137
-
138
215
  // setParam from keyValue
139
216
  bool setParam(uchar_td* buf, ushort_td keylen)
140
217
  {
@@ -143,26 +220,28 @@ public:
143
220
  return true;
144
221
  }
145
222
 
146
- unsigned char* writeBuffer(unsigned char* p, bool estimate, bool end,
223
+ int size(bool isTransactd) const
224
+ {
225
+ if (!isTransactd)
226
+ return len;
227
+ return sizeof(len) + len;
228
+ }
229
+
230
+ unsigned char* writeBuffer(unsigned char* p, bool end,
147
231
  bool isTransactd) const
148
232
  {
149
233
  int n = sizeof(len);
150
- if (!estimate)
151
- {
152
- if (isTransactd)
153
- memcpy(p, &len, n);
154
- else
155
- n = 0;
156
- memcpy(p + n, data, len);
157
- }
158
- else if (!isTransactd)
234
+ if (isTransactd)
235
+ memcpy(p, &len, n);
236
+ else
159
237
  n = 0;
160
-
238
+ memcpy(p + n, data, len);
161
239
  return p + n + len;
162
240
  }
163
241
  };
164
242
 
165
- struct logic
243
+ /* logic decrare DLLLIB for test_tdclcpp Windows*/
244
+ struct DLLLIB logic
166
245
  {
167
246
  unsigned char type;
168
247
  unsigned short len;
@@ -170,15 +249,39 @@ struct logic
170
249
  unsigned char logType;
171
250
  char opr;
172
251
  unsigned char* data;
252
+ unsigned int databuflen;
253
+ short fieldNum;
254
+ bool placeHolder;
173
255
 
174
256
  public:
175
- logic() : data(NULL) {}
257
+ logic() : data(NULL), databuflen(0), placeHolder(false) {}
258
+
259
+ ~logic() { delete[] data;}
176
260
 
177
- ~logic() { delete[] data; }
261
+ /* Important for vector erase */
262
+ logic& operator=(const logic& r)
263
+ {
264
+ if (this != &r)
265
+ {
266
+ if (data != r.data)
267
+ delete[] data;
268
+ type = r.type;
269
+ len = r.len;
270
+ pos = r.pos;
271
+ logType = r.logType;
272
+ opr = r.opr;
273
+ data = r.data;
274
+ databuflen = r.databuflen;
275
+ fieldNum = r.fieldNum;
276
+ placeHolder = r.placeHolder;
277
+ const_cast<logic&>(r).data = NULL; //Important for vector erase
278
+ }
279
+ return *this;
280
+ }
178
281
 
179
- size_t getLength()
282
+ int size() const
180
283
  {
181
- return sizeof(logic) - sizeof(unsigned char*) + getDatalen();
284
+ return (int)((unsigned char*)&data - &type) + getDatalen();
182
285
  }
183
286
 
184
287
  void setFieldParam(fielddef* fd)
@@ -195,7 +298,7 @@ public:
195
298
  return len;
196
299
  }
197
300
 
198
- bool setCompFiled(table* tb, short index, const _TCHAR* name)
301
+ bool setCompFiled(table* tb, const _TCHAR* name)
199
302
  {
200
303
  short tmp = tb->fieldNumByName(name);
201
304
  if (tmp != -1)
@@ -209,28 +312,58 @@ public:
209
312
  return false;
210
313
  }
211
314
 
212
- void allocBuffer(int size)
315
+ unsigned char* allocBuffer(unsigned int size)
316
+ {
317
+ if (databuflen < size + 2)
318
+ {
319
+ if (data)
320
+ {
321
+ delete[] data;
322
+ data = NULL;
323
+ }
324
+ databuflen = size + 2;
325
+ }
326
+ if (!data)
327
+ data = new unsigned char[databuflen];
328
+ memset(data, 0, databuflen);
329
+ return data;
330
+ }
331
+
332
+ template <class T>
333
+ inline unsigned int valueLen(const T /*value*/, unsigned int size)
334
+ {
335
+ return size;
336
+ }
337
+
338
+ inline unsigned int valueLen(const _TCHAR* value, unsigned int /*size*/)
213
339
  {
214
- if (data)
215
- delete[] data;
216
- data = new unsigned char[size + 2];
217
- memset(data, 0, size + 2);
340
+ return (unsigned int)_tcslen(value);
218
341
  }
219
342
 
220
- void copyToBuffer(table* tb, short index, bool part)
343
+ template <class T>
344
+ void setValue(table* tb, const T value)
221
345
  {
222
- fielddef* fd = &tb->tableDef()->fieldDefs[index];
223
- const uchar_td* ptr = (const uchar_td*)tb->fieldPtr(index);
224
- int varlen = varlenForFilter(*fd);
225
- int copylen = compDataLen(*fd, ptr, part);
346
+ if (logType & CMPLOGICAL_FIELD)
347
+ return;
348
+ fielddef fdd = tb->tableDef()->fieldDefs[fieldNum];
349
+ fdd.pos = 0;
350
+ uchar_td* buf = allocBuffer(fdd.len);
351
+ field fd(buf, fdd, tb->m_fddefs);
352
+ fd = value;
353
+ bool part = fd.isCompPartAndMakeValue();
354
+ int varlen = fdd.varLenByteForKey();
355
+ int copylen = compDataLen(fdd, buf, part);
226
356
  len = varlen + copylen;
227
- allocBuffer(len);
228
- uchar_td* to = (uchar_td*)data;
229
- if (varlen)
230
- memcpy(to, ptr, varlen);
231
- memcpy(to + varlen, fd->keyData(ptr), copylen);
357
+ if (fdd.blobLenBytes())
358
+ {
359
+ data = new unsigned char[len + 2];
360
+ if (varlen)
361
+ memcpy(data, buf, varlen);
362
+ memcpy(data + varlen, fdd.keyData(buf), copylen);
363
+ delete [] buf;
364
+ }
232
365
 
233
- if (!part && (fd->varLenBytes() || fd->blobLenBytes()))
366
+ if (!part && (fdd.varLenBytes() || fdd.blobLenBytes()))
234
367
  logType |= CMPLOGICAL_VAR_COMP_ALL; // match complate
235
368
  }
236
369
 
@@ -239,7 +372,8 @@ public:
239
372
  {
240
373
  logType = getFilterLogicTypeCode(type);
241
374
  opr = combine;
242
- short fieldNum = tb->fieldNumByName(name);
375
+ fieldNum = tb->fieldNumByName(name);
376
+ placeHolder = false;
243
377
  if ((logType != 255) && (fieldNum != -1))
244
378
  {
245
379
  bool ret = true;
@@ -247,34 +381,29 @@ public:
247
381
  setFieldParam(fd);
248
382
 
249
383
  if (compField)
250
- ret = setCompFiled(tb, fieldNum, value); // value is field name
384
+ ret = setCompFiled(tb, value); // value is field name
251
385
  else
252
386
  {
253
- fields fds(*tb);
254
- field fd = fds[fieldNum];
255
- fd = value;
256
- bool part = fd.isCompPartAndMakeValue();
257
- copyToBuffer(tb, fieldNum, part);
387
+ if (_tcscmp(value, _T("?"))==0)
388
+ placeHolder = true;
389
+ setValue(tb, value);
258
390
  }
259
391
  return ret;
260
392
  }
261
393
  return false;
262
394
  }
263
395
 
264
- unsigned char* writeBuffer(unsigned char* p, bool estimate, bool end) const
396
+ unsigned char* writeBuffer(unsigned char* p, bool end, bool preparingMode) const
265
397
  {
266
- int n = sizeof(logic) - sizeof(unsigned char*);
267
- if (!estimate)
268
- {
269
- memcpy(p, this, n);
270
- if (end)
271
- *(p + n - 1) = eCend;
272
- }
398
+ int n = (int)((unsigned char*)&data - &type);
399
+ memcpy(p, this, n);
400
+ if (end)
401
+ *(p + n - 1) = eCend;
402
+ if (preparingMode && placeHolder)
403
+ *(p + n - 1) |= FILTER_COMBINE_PREPARE;
273
404
  p += n;
274
-
275
405
  n = getDatalen();
276
- if (!estimate)
277
- memcpy(p, data, n);
406
+ memcpy(p, data, n);
278
407
  return p + n;
279
408
  }
280
409
 
@@ -293,14 +422,19 @@ public:
293
422
  {
294
423
  assert(src);
295
424
  assert(src->data);
296
- unsigned char* tmp = data;
297
- data = new unsigned char[len + src->len + 2];
298
- memcpy(data, tmp, len);
299
- memcpy(data + len, src->data, src->len);
425
+ //copy before
426
+ databuflen = len + src->len + 2;
427
+ unsigned char* tmp = new unsigned char[databuflen];
428
+ memcpy(tmp, data, len);
429
+ delete[] data;
430
+ //join next
431
+ memcpy(tmp + len, src->data, src->len);
300
432
  len += src->len;
301
433
  type = ft_string; // compare by memcmp
302
434
  opr = src->opr;
303
- delete[] tmp;
435
+ data = tmp;
436
+ delete [] src->data;
437
+ src->data = NULL;
304
438
  }
305
439
  };
306
440
 
@@ -316,13 +450,17 @@ private:
316
450
  };
317
451
  struct
318
452
  {
319
- int ilen : 28;
320
- int itype : 4;
453
+ unsigned int ilen : 28;
454
+ unsigned int itype : 4;
321
455
  };
322
456
  };
323
457
 
324
458
  public:
325
- unsigned short rejectCount;
459
+ union
460
+ {
461
+ unsigned short rejectCount;
462
+ unsigned short preparedId;
463
+ };
326
464
  unsigned short logicalCount;
327
465
  header() : len(0), rejectCount(1), logicalCount(0)
328
466
  {
@@ -339,14 +477,13 @@ public:
339
477
  type[1] = 0x00;
340
478
  }
341
479
 
342
- void setPositionType(bool incCurrent, bool withBookmark, bool isTransactd)
480
+ void setPositionType(bool incCurrent, bool isTransactd, int tp)
343
481
  {
344
482
  if (isTransactd)
345
483
  {
346
484
  itype = incCurrent ? FILTER_CURRENT_TYPE_INC
347
485
  : FILTER_CURRENT_TYPE_NOTINC;
348
- if (!withBookmark)
349
- itype |= FILTER_CURRENT_TYPE_NOBOOKMARK;
486
+ itype |= tp;
350
487
  }
351
488
  else
352
489
  {
@@ -368,7 +505,6 @@ public:
368
505
  if (isTransactd)
369
506
  return (itype & FILTER_CURRENT_TYPE_NOBOOKMARK) ? 0 : BOOKMARK_SIZE;
370
507
  assert(type[0]);
371
- // if (type[1] == 'N') return 0;
372
508
  return BOOKMARK_SIZE;
373
509
  }
374
510
 
@@ -387,89 +523,120 @@ public:
387
523
  len = size;
388
524
  }
389
525
 
390
- unsigned char* writeBuffer(unsigned char* p, bool estimate) const
526
+ unsigned char* writeBuffer(unsigned char* p, unsigned short prepareId) const
391
527
  {
392
528
  int n = sizeof(header);
393
- if (!estimate)
394
- memcpy(p, this, n);
529
+ memcpy(p, this, n);
530
+ if (prepareId)
531
+ memcpy(p + 4, &prepareId, sizeof(unsigned short));
395
532
  return p + n;
396
533
  }
534
+
535
+ inline int size() const { return sizeof(header); }
397
536
  };
398
537
  #pragma pack(pop)
399
538
  pragma_pop;
400
539
 
401
- class recordBackup
540
+ class autoBackup
402
541
  {
403
- char* m_buf;
404
542
  table* m_tb;
405
-
543
+ char* m_buf;
544
+ int m_len;
406
545
  public:
407
- recordBackup(table* tb) : m_tb(tb)
546
+ autoBackup(table* tb, std::vector<char>& b):m_tb(tb),
547
+ m_len(m_tb->tableDef()->maxRecordLen)
408
548
  {
409
- m_buf = new char[m_tb->buflen()];
410
- memcpy(m_buf, m_tb->fieldPtr(0), m_tb->buflen());
549
+ b.resize(m_len);
550
+ m_buf = &b[0];
551
+ memcpy(m_buf, m_tb->fieldPtr(0), m_len);
411
552
  }
412
553
 
413
- ~recordBackup()
554
+ ~autoBackup()
414
555
  {
415
- memcpy(m_tb->fieldPtr(0), m_buf, m_tb->buflen());
416
- delete[] m_buf;
556
+ memcpy(m_tb->fieldPtr(0), m_buf, m_len);
417
557
  }
418
558
  };
419
559
 
560
+
420
561
  class filter
421
562
  {
422
563
  table* m_tb;
423
564
  header m_hd;
424
565
  resultDef m_ret;
425
- std::vector<resultField*> m_fields;
566
+ std::vector<resultField> m_fields;
426
567
  std::vector<short> m_selectFieldIndexes;
427
568
  std::vector<logic> m_logics;
428
569
  std::vector<seek> m_seeks;
429
- uchar_td* m_seeksDataBuffer;
570
+ std::vector<uchar_td> m_seeksDataBuffer;
571
+ std::vector<short> m_placeHolderIndexes;
572
+ size_t m_seeksWritedCount;
573
+ size_t m_seeksLimitIndex;
574
+ std::vector<char> m_recordBackup;
575
+ uchar_td* m_buftmp;
430
576
 
431
577
  int m_extendBuflen;
432
- bool m_ignoreFields;
433
- bool m_seeksMode;
434
- bool m_useOptimize;
435
- bool m_withBookmark;
436
- size_t m_seeksWritedCount;
437
- size_t m_logicalLimitCount;
578
+ short m_stat;
579
+ ushort_td m_preparedId;
438
580
  table::eFindType m_direction;
439
- bool m_isTransactd;
440
- bool m_hasManyJoin;
581
+ queryBase::eOptimize m_cachedOptimize;
582
+ struct
583
+ {
584
+ bool m_ignoreFields : 1;
585
+ bool m_seeksMode : 1;
586
+ bool m_useOptimize : 1;
587
+ bool m_withBookmark : 1;
588
+ bool m_isTransactd : 1;
589
+ bool m_hasManyJoin : 1;
590
+ bool m_preparingMode : 1;
591
+ bool m_ddba : 1;
592
+
593
+ };
594
+
595
+ struct bufSize
596
+ {
597
+ bufSize():logic(0), seeks(0), select(0),retRowSize(0) {}
598
+ void clear() { logic = 0; seeks = 0; select = 0; retRowSize = 0;}
599
+ int logic;
600
+ int seeks;
601
+ int select;
602
+ int retRowSize;
603
+ }bsize;
604
+
441
605
  inline int maxDataBuffer()
442
606
  {
607
+ //return 2048; //Small buffer test
443
608
  return m_isTransactd ? TDAP_MAX_DATA_SIZE : BTRV_MAX_DATA_SIZE;
444
609
  }
445
610
 
446
611
  void addAllFields()
447
612
  {
448
- resultField* r = new resultField();
449
- r->len = (ushort_td)m_tb->tableDef()->maxRecordLen;
450
- r->pos = 0;
451
- m_fields.push_back(r);
613
+ m_fields.resize(1);
614
+ resultField& r = m_fields[0];
615
+ r.len = (ushort_td)m_tb->tableDef()->maxRecordLen;
616
+ r.pos = 0;
617
+ bsize.select = r.size();
618
+ bsize.retRowSize = r.len;
452
619
  }
453
620
 
454
- bool addSelect(const _TCHAR* name)
621
+ bool addSelect(resultField& r, const _TCHAR* name)
455
622
  {
456
- resultField* r = new resultField();
457
- int fieldNum = r->setParam(m_tb, name);
623
+ int fieldNum = r.setParam(m_tb, name);
458
624
  if (fieldNum != -1)
459
625
  {
460
- m_fields.push_back(r);
461
626
  m_selectFieldIndexes.push_back(fieldNum);
627
+ bsize.select += r.size();
628
+ bsize.retRowSize += r.len;
462
629
  return true;
463
630
  }
464
- delete r;
465
631
  return false;
466
632
  }
467
633
 
468
634
  bool setSelect(const std::vector<std::_tstring>& selects)
469
635
  {
636
+ m_fields.resize(selects.size());
470
637
  for (size_t i = 0; i < selects.size(); ++i)
471
638
  {
472
- if (!addSelect(selects[i].c_str()))
639
+ if (!addSelect(m_fields[i], selects[i].c_str()))
473
640
  return false;
474
641
  }
475
642
  return true;
@@ -482,7 +649,7 @@ class filter
482
649
  if (where.size() < 3)
483
650
  return false;
484
651
  m_logics.resize(m_logics.size() + (where.size() + 1) / 4);
485
-
652
+ m_hd.logicalCount = (ushort_td)m_logics.size();
486
653
  int index = 0;
487
654
  for (size_t i = 0; i < where.size(); i += 4)
488
655
  {
@@ -507,92 +674,123 @@ class filter
507
674
  else
508
675
  return false;
509
676
  }
510
- if (!m_logics[index++].setParam(m_tb, where[i].c_str(),
511
- where[i + 1].c_str(), value.c_str(),
512
- combine, compField))
677
+ logic& l = m_logics[index];
678
+ if (!l.setParam(m_tb, where[i].c_str(),
679
+ where[i + 1].c_str(), value.c_str(), combine, compField))
513
680
  return false;
681
+ if (l.placeHolder)
682
+ m_placeHolderIndexes.push_back(index);
683
+ bsize.logic += l.size();
684
+ ++index;
514
685
  }
515
686
  return true;
516
687
  }
517
688
 
518
- inline void setSeekValue(short fieldNum, const std::_tstring& s)
689
+ uchar_td* reallocSeeksDataBuffer(size_t size)
519
690
  {
520
- m_tb->setFV(fieldNum, s.c_str());
691
+ if (m_seeksDataBuffer.size() < size)
692
+ m_seeksDataBuffer.resize(size);
693
+ uchar_td* dataBuf = &m_seeksDataBuffer[0];
694
+ return dataBuf;
521
695
  }
522
696
 
523
- inline void setSeekValue(short fieldNum, const keyValuePtr& v)
697
+ inline const _TCHAR* c_str_v(const _TCHAR* v) const { return v; }
698
+
699
+ inline const _TCHAR* c_str_v(const std::_tstring& v) const { return v.c_str(); }
700
+
701
+ // Need covert data types
702
+ template <class T>
703
+ bool doSsetSeekValues(keydef* kd, int joinKeySize, const T& keyValues, size_t size, uchar_td* dataBuf )
524
704
  {
525
- if (v.type & KEYVALUE_STR)
526
- m_tb->setFV(fieldNum, (_TCHAR*)v.ptr);
527
- else
705
+ autoBackup recb(m_tb, m_recordBackup);
706
+ int index = 0;
707
+ bsize.seeks = 0;
708
+ for (size_t i = 0; i < size; i += joinKeySize)
528
709
  {
529
- fielddef& fd = m_tb->tableDef()->fieldDefs[fieldNum];
530
- void* p = m_tb->fieldPtr(fieldNum);
531
-
532
- ushort_td len = std::min<ushort_td>(v.len, fd.len);
533
- memset(p, 0, fd.len);
534
- memcpy(p, v.ptr, len);
710
+ for (int j = 0; j < joinKeySize; ++j)
711
+ m_tb->setFV(kd->segments[j].fieldNum, c_str_v(keyValues[i + j]));
712
+ seek& l = m_seeks[index];
713
+ ushort_td len = m_tb->writeKeyDataTo(dataBuf, joinKeySize);
714
+ if (!l.setParam(dataBuf, len))
715
+ return false;
716
+ bsize.seeks += l.size(m_isTransactd);
717
+ dataBuf += len;
718
+ ++index;
535
719
  }
720
+ return true;
536
721
  }
537
722
 
538
- template <class vector_type>
539
- bool setSeeks(const vector_type& keyValues, const queryBase* q)
723
+ // no need covert data types
724
+ bool doSsetSeekValues(keydef* kd, int joinKeySize, const std::vector<keyValuePtr>& keyValues, size_t size, uchar_td* dataBuf )
540
725
  {
541
- int keySize = q->getJoinKeySize();
542
- // Check key values
543
- keydef* kd = &m_tb->tableDef()->keyDefs[m_tb->keyNum()];
544
- int joinKeySize = kd->segmentCount;
545
- if (keySize != 0)
726
+ int index = 0;
727
+ bsize.seeks = 0;
728
+ fielddef* fds = m_tb->tableDef()->fieldDefs;
729
+ for (size_t i = 0; i < size; i += joinKeySize)
546
730
  {
547
- // Check specify key size is smoller than kd->segmentCount or equal
548
- if (kd->segmentCount < keySize)
549
- return false;
550
- joinKeySize = keySize;
551
- m_withBookmark = m_hasManyJoin =
552
- (kd->segmentCount != joinKeySize) || kd->segments[0].flags.bit0;
553
-
554
- // Check when m_hasManyJoin need set joinHasOneOrHasMany
555
- if (m_hasManyJoin &&
556
- !(q->getOptimize() & queryBase::joinHasOneOrHasMany))
731
+ seek& l = m_seeks[index];
732
+ uchar_td* to = dataBuf;
733
+ for (int j = 0; j < joinKeySize; ++j)
734
+ {
735
+ const keyValuePtr& v = keyValues[i + j];
736
+ fielddef& fd = fds[kd->segments[j].fieldNum];
737
+ to = fd.keyCopy(to, (uchar_td*)v.ptr, v.len);
738
+ }
739
+ if (!l.setParam(dataBuf, (ushort_td)(to - dataBuf)))
557
740
  return false;
741
+ bsize.seeks += l.size(m_isTransactd);
742
+ dataBuf = to;
743
+ ++index;
558
744
  }
559
-
560
- if (keyValues.size() % joinKeySize)
745
+ return true;
746
+ }
747
+
748
+ bool prebuiltSeeks( keydef* kd, size_t size, const queryBase* q, int& keySize, uchar_td** dataBuf)
749
+ {
750
+ // Check specify key size is smoller than kd->segmentCount or equal
751
+ if (keySize == 0)
752
+ keySize = kd->segmentCount;
753
+ else if (kd->segmentCount < keySize)
754
+ return false;
755
+ if (size % keySize)
561
756
  return false;
562
- // Check uniqe key
563
- if (kd->segments[0].flags.bit0 && !queryBase::joinHasOneOrHasMany)
757
+
758
+ m_hasManyJoin = (kd->segmentCount != keySize) || kd->segments[0].flags.bit0;
759
+ if (m_hasManyJoin)
760
+ m_withBookmark = true;
761
+ if (q && m_hasManyJoin &&
762
+ !(q->getOptimize() & queryBase::joinHasOneOrHasMany))
564
763
  return false;
565
- m_seeks.resize(keyValues.size() / joinKeySize);
764
+ m_seeks.resize(size / keySize);
566
765
  int maxKeylen = 0;
567
- for (int j = 0; j < joinKeySize; ++j)
766
+ for (int j = 0; j < keySize; ++j)
568
767
  maxKeylen +=
569
768
  m_tb->tableDef()->fieldDefs[kd->segments[j].fieldNum].len + 2;
570
769
 
571
770
  // alloc databuffer
572
- if (m_seeksDataBuffer)
573
- delete[] m_seeksDataBuffer;
574
-
575
- m_seeksDataBuffer = new uchar_td[maxKeylen * m_seeks.size()];
576
- memset(m_seeksDataBuffer, 0, maxKeylen * m_seeks.size());
577
- uchar_td* dataBuf = m_seeksDataBuffer;
578
-
579
- int index = 0;
580
- for (size_t i = 0; i < keyValues.size(); i += joinKeySize)
581
- {
582
- for (int j = 0; j < joinKeySize; ++j)
583
- setSeekValue(kd->segments[j].fieldNum, keyValues[i + j]);
584
- seek* l = &m_seeks[index];
585
- ushort_td len = m_tb->writeKeyDataTo(dataBuf, joinKeySize);
586
- if (!l->setParam(dataBuf, len))
587
- return false;
588
- dataBuf += len;
589
- ++index;
590
- }
771
+ *dataBuf = reallocSeeksDataBuffer(maxKeylen * m_seeks.size());
772
+ m_hd.rejectCount = 0;
591
773
  m_seeksMode = true;
592
774
  m_seeksWritedCount = 0;
593
775
  return true;
594
776
  }
595
777
 
778
+ template <class vector_type>
779
+ bool setSeeks(const vector_type& keyValues, const queryBase* q)
780
+ {
781
+ int keySize = q->getJoinKeySize();
782
+ uchar_td* dataBuf;
783
+ keydef* kd = &m_tb->tableDef()->keyDefs[m_tb->keyNum()];
784
+
785
+ if (!prebuiltSeeks(kd, keyValues.size(), q, keySize, &dataBuf))
786
+ return false;
787
+
788
+ if (!doSsetSeekValues(kd, keySize, keyValues, keyValues.size(), dataBuf))
789
+ return false;
790
+
791
+ return true;
792
+ }
793
+
596
794
  bool doSetFilter(const queryBase* q)
597
795
  {
598
796
  cleanup();
@@ -602,7 +800,7 @@ class filter
602
800
  m_useOptimize = ((q->getOptimize() & queryBase::combineCondition) ==
603
801
  queryBase::combineCondition);
604
802
  m_withBookmark = q->isBookmarkAlso();
605
- recordBackup recb(m_tb);
803
+ m_cachedOptimize = q->getOptimize();
606
804
 
607
805
  if (q->isAll())
608
806
  addAllFields();
@@ -629,17 +827,13 @@ class filter
629
827
 
630
828
  int resultRowSize(bool ignoreFields) const
631
829
  {
632
-
633
830
  int recordLen = m_hd.bookmarkSize(m_isTransactd) + DATASIZE_BYTE;
634
831
  if (!ignoreFields)
635
- {
636
- for (size_t i = 0; i < m_fields.size(); ++i)
637
- recordLen += m_fields[i]->len;
638
- }
832
+ recordLen += bsize.retRowSize;
639
833
  return recordLen;
640
834
  }
641
835
 
642
- int calcMaxRows()
836
+ int calcMaxResultRows()
643
837
  {
644
838
  return maxDataBuffer() / resultRowSize(m_ignoreFields);
645
839
  }
@@ -656,167 +850,272 @@ class filter
656
850
 
657
851
  for (int i = (int)m_logics.size() - 2; i >= 0; --i)
658
852
  {
659
-
660
853
  logic& la = m_logics[i + 1];
661
854
  logic& lb = m_logics[i];
662
855
  if (la.canJoin(false) && lb.canJoin(true) && lb.isNextFiled(&la))
663
856
  {
857
+ bsize.logic -= lb.size();
858
+ bsize.logic -= la.size();
664
859
  lb.joinAfter(&la);
665
- // delete la;
860
+ bsize.logic += lb.size();
666
861
  m_logics.erase(m_logics.begin() + i + 1);
862
+ m_hd.logicalCount--;
667
863
  }
668
864
  }
669
865
  }
670
866
 
671
- int doWriteBuffer(bool estimate)
672
- {
673
- unsigned char* p = (unsigned char*)m_tb->dataBak();
674
- unsigned char* start = p;
675
-
676
- m_hd.logicalCount = (ushort_td)m_logicalLimitCount;
677
- if (m_ignoreFields)
678
- m_ret.fieldCount = 0;
679
- else
680
- m_ret.fieldCount = (ushort_td)m_fields.size();
681
-
682
- size_t first = 0, last = m_logicalLimitCount;
683
- if (m_seeksMode)
684
- {
685
- first = m_seeksWritedCount;
686
- last = std::min<size_t>(calcMaxRows() + m_seeksWritedCount,
687
- m_logicalLimitCount);
688
- m_hd.rejectCount = 0;
689
- if (m_hasManyJoin)
690
- m_ret.maxRows = 0;
691
- else
692
- m_ret.maxRows = m_hd.logicalCount = (ushort_td)(last - first);
693
- }
694
- if (m_ret.maxRows == 0)
695
- m_ret.maxRows =
696
- (unsigned short)std::min<int>(calcMaxRows(), USHRT_MAX);
697
-
698
- p = m_hd.writeBuffer(p, estimate);
699
- if (m_seeksMode)
700
- {
701
- for (size_t i = first; i < last; ++i)
702
- p = m_seeks[i].writeBuffer(p, estimate, (i == (last - 1)),
703
- true);
704
- if (!estimate)
705
- m_seeksWritedCount += m_hd.logicalCount;
706
- }
707
- else
708
- {
709
- for (size_t i = first; i < last; ++i)
710
- p = m_logics[i].writeBuffer(p, estimate, (i == (last - 1)));
711
- }
712
-
713
- p = m_ret.writeBuffer(p, estimate);
714
-
715
- if (!m_ignoreFields)
716
- {
717
- for (size_t i = 0; i < m_fields.size(); ++i)
718
- p = m_fields[i]->writeBuffer(p, estimate);
719
- }
720
-
721
- // write total length
722
- int len = (int)(p - start);
723
- if (!estimate)
724
- {
725
- m_hd.setLen(len, m_isTransactd);
726
- m_hd.writeBuffer(start, false);
727
- }
728
- return len;
729
- }
730
-
731
867
  // use seeksMode only
732
868
  int calcLogicalCutsize(int oversize)
733
869
  {
734
870
  int cutsize = 0;
735
- for (size_t i = m_hd.logicalCount - 1; i != 0; --i)
871
+ for (size_t i = m_seeksLimitIndex - 1; i >= m_seeksWritedCount; --i)
736
872
  {
737
- cutsize += (int)m_seeks[i + m_seeksWritedCount].getLength();
873
+ cutsize += (int)m_seeks[i].size(m_isTransactd);
738
874
  if (oversize - cutsize < 0)
739
875
  {
740
- m_logicalLimitCount = i;
876
+ m_seeksLimitIndex = i;
741
877
  return cutsize;
742
878
  }
743
879
  }
744
880
  return 0;
745
881
  }
746
882
 
747
- bool allocDataBuffer()
883
+ // Calc send buffer size and set last index of seeksMode can sent (m_seeksLimitIndex).
884
+ int calcSendBuflen()
748
885
  {
749
- joinLogic();
750
- m_logicalLimitCount = m_seeksMode ? m_seeks.size() : m_logics.size();
751
- int len = doWriteBuffer(true);
752
- if (len > maxDataBuffer())
886
+ int len = m_hd.size();
887
+
888
+ if (!m_preparedId)
753
889
  {
754
- if (m_seeksMode)
755
- len -= calcLogicalCutsize(len - maxDataBuffer() + 1);
890
+ len += m_ret.size();
891
+ if (!m_ignoreFields)
892
+ {
893
+ len += bsize.select;
894
+ m_ret.fieldCount = (ushort_td)m_fields.size();
895
+ }else
896
+ m_ret.fieldCount = 0;
897
+ }
898
+ if (m_seeksMode)
899
+ {
900
+ int maxRows = calcMaxResultRows();
901
+ m_seeksLimitIndex = std::min<size_t>(maxRows, m_seeks.size() - m_seeksWritedCount) + m_seeksWritedCount;
902
+ if (m_seeksWritedCount == 0 && m_seeksLimitIndex == m_seeks.size())
903
+ len += bsize.seeks;
756
904
  else
757
- return false;
905
+ for (size_t i = m_seeksWritedCount; i < m_seeksLimitIndex; ++i)
906
+ len += m_seeks[i].size(m_isTransactd);
907
+
908
+ if (len > maxDataBuffer())
909
+ len -= calcLogicalCutsize(len - maxDataBuffer() + 1);
910
+
911
+ m_ret.maxRows = m_hd.logicalCount = (ushort_td)(m_seeksLimitIndex - m_seeksWritedCount);
912
+ if (m_hasManyJoin)
913
+ m_ret.maxRows = (unsigned short)std::min<int>(maxRows, USHRT_MAX);
758
914
  }
759
- // m_hd.len = len;//lost 2byte data at transactd
760
- int resultLen = (int)resultBufferNeedSize();
761
- if (resultLen > maxDataBuffer())
915
+ else
762
916
  {
763
- /* change the max rows fit to a max buffer size */
764
- m_ret.maxRows = calcMaxRows();
765
- resultLen = resultBufferNeedSize();
917
+ len += bsize.logic;
918
+ // change the max rows fit to a max buffer size
919
+ if (m_ret.maxRows == 0)
920
+ m_ret.maxRows =
921
+ (unsigned short)std::min<int>(calcMaxResultRows(), USHRT_MAX);
922
+ else if (resultBufferNeedSize() > maxDataBuffer())
923
+ m_ret.maxRows = calcMaxResultRows();
766
924
  }
925
+
926
+ return len;
927
+ }
767
928
 
768
- m_extendBuflen = std::max<int>((int)len, resultLen);
769
- m_extendBuflen =
770
- std::max<int>(m_extendBuflen, m_tb->tableDef()->maxRecordLen);
929
+ bool allocDataBuffer(int len)
930
+ {
931
+ // m_hd.len = len;//lost 2byte data at transactd
932
+ m_extendBuflen = (int)resultBufferNeedSize();
771
933
  if (fieldSelected() || m_tb->valiableFormatType())
772
- m_extendBuflen += m_tb->buflen();
934
+ m_extendBuflen += m_tb->tableDef()->maxRecordLen;
935
+ m_tb->reallocDataBuffer(m_ddba ? len : m_extendBuflen);
936
+ return true;
937
+ }
773
938
 
774
- if ((int)m_tb->buflen() < m_extendBuflen)
939
+
940
+ int doWriteBuffer()
941
+ {
942
+ #ifdef _DEBUG
943
+ int tmpLen = calcSendBuflen();
944
+ #endif
945
+ unsigned char* p = (unsigned char*)m_tb->dataBak();
946
+ unsigned char* start = p;
947
+ p = m_hd.writeBuffer(p, m_preparedId);
948
+ if (m_seeksMode)
775
949
  {
776
- m_tb->setDataBak((void*)realloc(m_tb->dataBak(), m_extendBuflen));
777
- m_tb->setData(m_tb->dataBak());
950
+ for (size_t i = m_seeksWritedCount; i < m_seeksLimitIndex; ++i)
951
+ p = m_seeks[i].writeBuffer(p, (i == (m_seeksLimitIndex - 1)), true);
952
+ m_seeksWritedCount += m_hd.logicalCount;
778
953
  }
779
- return true;
954
+ else
955
+ {
956
+ for (size_t i = 0; i < m_logics.size(); ++i)
957
+ p = m_logics[i].writeBuffer(p, (i == (m_logics.size() - 1)), m_preparingMode);
958
+ }
959
+ if (!m_preparedId)
960
+ {
961
+ p = m_ret.writeBuffer(p);
962
+ if (!m_ignoreFields)
963
+ {
964
+ for (size_t i = 0; i < m_fields.size(); ++i)
965
+ p = m_fields[i].writeBuffer(p);
966
+ }
967
+ }
968
+ // write total length
969
+ int len = (int)(p - start);
970
+ m_hd.setLen(len, m_isTransactd);
971
+ m_hd.writeBuffer(start, m_preparedId);
972
+
973
+ #ifdef _DEBUG
974
+ assert(len == tmpLen);
975
+ #endif
976
+ return len;
780
977
  }
978
+
781
979
 
782
- public:
783
980
  filter(table* tb)
784
- : m_tb(tb), m_seeksDataBuffer(NULL), m_ignoreFields(false),
785
- m_seeksMode(false), m_useOptimize(true), m_withBookmark(true),
786
- m_seeksWritedCount(0), m_hasManyJoin(false)
981
+ : m_tb(tb), m_extendBuflen(0), m_stat(0), m_preparedId(0),
982
+ m_ignoreFields(false), m_seeksMode(false), m_useOptimize(true),
983
+ m_withBookmark(true), m_seeksWritedCount(0), m_hasManyJoin(false),
984
+ m_preparingMode(false),m_ddba(false)
787
985
  {
788
986
  m_isTransactd = m_tb->isUseTransactd();
987
+ m_ddba = m_isTransactd;
789
988
  }
790
989
 
791
- ~filter() { cleanup(); }
990
+ ~filter() {}
792
991
 
992
+ public:
793
993
  void cleanup()
794
994
  {
795
- for (size_t i = 0; i < m_fields.size(); ++i)
796
- delete m_fields[i];
797
995
  m_selectFieldIndexes.clear();
798
996
  m_fields.clear();
799
997
  m_logics.clear();
800
998
  m_seeks.clear();
801
999
  m_hd.reset();
802
1000
  m_ret.reset();
1001
+ m_placeHolderIndexes.clear();
803
1002
  m_ignoreFields = false;
804
1003
  m_seeksMode = false;
805
1004
  m_seeksWritedCount = 0;
806
1005
  m_useOptimize = true;
807
- delete[] m_seeksDataBuffer;
808
- m_seeksDataBuffer = NULL;
809
1006
  m_hasManyJoin = false;
1007
+ m_preparingMode = false;
1008
+ m_preparedId = 0;
1009
+ m_stat = 0;
1010
+ bsize.clear();
810
1011
  }
811
1012
 
1013
+ void clearSeeks() { m_seeks.clear(); m_seeksWritedCount = 0; }
1014
+
1015
+ queryBase::eOptimize cachedOptimaize() const { return m_cachedOptimize; }
1016
+
1017
+ void setPreparingMode(bool v){ m_preparingMode = v;}
1018
+
1019
+ void setServerPreparedId(ushort_td v) { m_preparedId = v; }
1020
+
1021
+ ushort_td preparedId() const { return m_preparedId; }
1022
+
812
1023
  bool setQuery(const queryBase* q)
813
1024
  {
1025
+ m_stat = 0;
814
1026
  bool ret = doSetFilter(q);
1027
+ if (m_placeHolderIndexes.size() && m_useOptimize)
1028
+ ret = false;
815
1029
  if (!ret)
816
1030
  cleanup();
817
1031
  return ret;
818
1032
  }
819
1033
 
1034
+ bool supplyValues(const std::vector<std::_tstring>& values)
1035
+ {
1036
+ if (m_placeHolderIndexes.size() != values.size())
1037
+ return false;
1038
+ for (int i = 0;i< (int)values.size();++i)
1039
+ supplyValue(i, values[i].c_str());
1040
+ return true;
1041
+ }
1042
+
1043
+ bool supplyValues(const _TCHAR* values[], int size)
1044
+ {
1045
+ if ((int)m_placeHolderIndexes.size() != size)
1046
+ return false;
1047
+ for (int i = 0;i< size;++i)
1048
+ supplyValue(i, values[i]);
1049
+ return true;
1050
+ }
1051
+
1052
+ template <class T>
1053
+ bool supplyValue(int placeHolderIndex, const T value)
1054
+ {
1055
+ if (placeHolderIndex < (int)m_placeHolderIndexes.size())
1056
+ {
1057
+ logic& l = m_logics[m_placeHolderIndexes[placeHolderIndex]];
1058
+ if (l.placeHolder)
1059
+ {
1060
+ bsize.logic -= l.size();
1061
+ l.setValue(m_tb, value);
1062
+ bsize.logic += l.size();
1063
+ return true;
1064
+ }
1065
+ }
1066
+ return false;
1067
+ }
1068
+
1069
+ template <class T>
1070
+ bool supplySeekValues(const T& values, size_t size, int keySize)
1071
+ {
1072
+ uchar_td* dataBuf;
1073
+ keydef* kd = &m_tb->tableDef()->keyDefs[m_tb->keyNum()];
1074
+
1075
+ if (!prebuiltSeeks(kd, size, NULL, keySize, &dataBuf))
1076
+ return false;
1077
+
1078
+ if (!doSsetSeekValues(kd, keySize, values, size, dataBuf))
1079
+ return false;
1080
+
1081
+ m_seeksMode = true;
1082
+ m_seeksWritedCount = 0;
1083
+ return true;
1084
+ }
1085
+
1086
+ bool beginSupplySeekValues(size_t size, int keySize)
1087
+ {
1088
+ keydef* kd = &m_tb->tableDef()->keyDefs[m_tb->keyNum()];
1089
+
1090
+ if (!prebuiltSeeks(kd, size, NULL, keySize, &m_buftmp))
1091
+ return false;
1092
+ m_seeksMode = true;
1093
+ m_seeksWritedCount = 0;
1094
+ bsize.seeks = 0;
1095
+ return true;
1096
+ }
1097
+
1098
+ bool supplySeekValue(const uchar_td* ptr[] , int len[], int keySize, int& index)
1099
+ {
1100
+ const tabledef* td = m_tb->tableDef();
1101
+ keydef* kd = &td->keyDefs[m_tb->keyNum()];
1102
+ fielddef* fds = td->fieldDefs;
1103
+
1104
+ seek& l = m_seeks[index];
1105
+ uchar_td* to = m_buftmp;
1106
+ for (int j = 0; j < keySize; ++j)
1107
+ {
1108
+ fielddef& fd = fds[kd->segments[j].fieldNum];
1109
+ to = fd.keyCopy(to, (uchar_td*)ptr[j], len[j]);
1110
+ }
1111
+ if (!l.setParam(m_buftmp, (ushort_td)(to - m_buftmp)))
1112
+ return false;
1113
+ bsize.seeks += l.size(m_isTransactd);
1114
+ m_buftmp = to;
1115
+ ++index;
1116
+ return true;
1117
+ }
1118
+
820
1119
  bool isWriteComleted() const
821
1120
  {
822
1121
  if (!m_seeksMode)
@@ -828,43 +1127,55 @@ public:
828
1127
 
829
1128
  inline void resetSeeksWrited() { m_seeksWritedCount = 0; }
830
1129
 
831
- void setPositionType(bool incCurrent)
1130
+ inline void setPositionType(bool incCurrent)
832
1131
  {
833
- m_hd.setPositionType(incCurrent, m_withBookmark, m_isTransactd);
1132
+ int type = 0;
1133
+ if (m_isTransactd)
1134
+ {
1135
+ if (m_preparedId)
1136
+ type |= FILTER_TYPE_SUPPLYVALUE;
1137
+ else if (m_preparingMode && (m_direction == table::findForword))
1138
+ type |= FILTER_TYPE_FORWORD;
1139
+
1140
+ if (!m_withBookmark)
1141
+ type |= FILTER_CURRENT_TYPE_NOBOOKMARK;
1142
+ if (m_seeksMode)
1143
+ type |= FILTER_TYPE_SEEKS;
1144
+
1145
+ }
1146
+ m_hd.setPositionType(incCurrent, m_isTransactd, type);
834
1147
  }
835
1148
 
836
- bool positionTypeNext() const
1149
+ inline bool positionTypeNext() const
837
1150
  {
838
1151
  return m_hd.positionTypeNext(m_isTransactd);
839
1152
  }
840
1153
 
841
- void setRejectCount(ushort_td v) { m_hd.rejectCount = v; }
842
- ushort_td rejectCount() const { return m_hd.rejectCount; }
1154
+ inline void setRejectCount(ushort_td v) { m_hd.rejectCount = v; }
1155
+ inline ushort_td rejectCount() const { return m_hd.rejectCount; }
843
1156
 
844
- void setMaxRows(ushort_td v) { m_ret.maxRows = v; }
845
- ushort_td maxRows() const { return m_ret.maxRows; }
1157
+ inline void setMaxRows(ushort_td v) { m_ret.maxRows = v; }
1158
+ inline ushort_td maxRows() const { return m_ret.maxRows; }
846
1159
 
847
- ushort_td recordCount() const { return maxRows(); }
1160
+ inline ushort_td recordCount() const { return maxRows(); }
848
1161
 
849
- void setPosTypeNext(bool v) { setPositionType(!v); }
1162
+ inline void setPosTypeNext(bool v) { setPositionType(!v); }
850
1163
 
851
1164
  uint_td exDataBufLen() const
852
1165
  {
853
1166
  if (fieldSelected() || m_tb->valiableFormatType())
854
- return m_extendBuflen - m_tb->buflen();
1167
+ return m_extendBuflen - m_tb->tableDef()->maxRecordLen;
855
1168
  return m_extendBuflen;
856
1169
  }
857
1170
 
858
- void init(table* pBao){};
859
-
860
- ushort_td fieldCount() const { return m_ret.fieldCount; }
1171
+ inline ushort_td fieldCount() const { return m_ret.fieldCount; }
861
1172
 
862
- void setFieldCount(ushort_td v) { m_ret.fieldCount = v; }
1173
+ inline void setFieldCount(ushort_td v) { m_ret.fieldCount = v; }
863
1174
 
864
- ushort_td fieldLen(int index) const
1175
+ inline ushort_td fieldLen(int index) const
865
1176
  {
866
1177
  assert(index < (int)m_fields.size());
867
- return m_fields[index]->len;
1178
+ return m_fields[index].len;
868
1179
  }
869
1180
 
870
1181
  ushort_td totalFieldLen() const
@@ -877,49 +1188,115 @@ public:
877
1188
  {
878
1189
  ushort_td recordLen = 0;
879
1190
  for (size_t i = 0; i < m_fields.size(); ++i)
880
- recordLen += m_fields[i]->len;
1191
+ recordLen += m_fields[i].len;
881
1192
  return recordLen;
882
1193
  }
883
1194
 
884
- ushort_td fieldOffset(int index) const
1195
+ inline ushort_td fieldOffset(int index) const
885
1196
  {
886
1197
  assert(index < (int)m_fields.size());
887
- return m_fields[index]->pos;
1198
+ return m_fields[index].pos;
888
1199
  }
889
1200
 
890
1201
  bool writeBuffer()
891
1202
  {
892
- if (allocDataBuffer())
893
- return (doWriteBuffer(false) > 0);
1203
+ // Preapare need not assigned seeks.
1204
+ if (m_preparingMode && m_seeksMode)
1205
+ return false;
1206
+ if (!m_isTransactd)
1207
+ m_preparingMode = false;
1208
+ if (!m_preparedId)
1209
+ joinLogic();
1210
+
1211
+ int len = calcSendBuflen();
1212
+ if (len > maxDataBuffer())
1213
+ return false; //Too many logics
1214
+
1215
+ if (allocDataBuffer(len))
1216
+ return (doWriteBuffer(/*false*/) > 0);
894
1217
  return false;
895
1218
  }
896
1219
 
897
- ushort_td extendBuflen() const { return m_extendBuflen; }
1220
+ inline ushort_td extendBuflen() const { return m_extendBuflen; }
898
1221
 
899
1222
  bool fieldSelected() const
900
1223
  {
901
- return !((m_fields.size() == 1) && (m_fields[0]->pos == 0) &&
902
- (m_fields[0]->len ==
1224
+ return !((m_fields.size() == 1) && (m_fields[0].pos == 0) &&
1225
+ (m_fields[0].len ==
903
1226
  (ushort_td)m_tb->tableDef()->maxRecordLen));
904
1227
  }
905
1228
 
906
- bool ignoreFields() const { return m_ignoreFields; }
1229
+ inline bool ignoreFields() const { return m_ignoreFields; }
907
1230
 
908
- int bookmarkSize() const { return m_hd.bookmarkSize(m_isTransactd); }
1231
+ inline int bookmarkSize() const { return m_hd.bookmarkSize(m_isTransactd); }
909
1232
 
910
1233
  /* The Ignore fields option don't use with multi seek operation.
911
1234
  because if a server are not found a record then a server return
912
1235
  error code in a bookmark field.
913
1236
  */
914
- void setIgnoreFields(bool v) { m_ignoreFields = v; }
915
- bool isSeeksMode() const { return m_seeksMode; }
916
- table::eFindType direction() const { return m_direction; }
917
- void setDirection(table::eFindType v) { m_direction = v; }
918
- const std::vector<short>& selectFieldIndexes()
1237
+ inline void setIgnoreFields(bool v) { m_ignoreFields = v; }
1238
+ inline bool isSeeksMode() const { return m_seeksMode; }
1239
+ inline table::eFindType direction() const { return m_direction; }
1240
+ inline bool setDirection(table::eFindType v)
1241
+ {
1242
+ if (m_preparedId == 0)
1243
+ m_direction = v;
1244
+ return (m_direction == v);
1245
+ }
1246
+ inline const std::vector<short>& selectFieldIndexes()
919
1247
  {
920
1248
  return m_selectFieldIndexes;
921
1249
  }
922
- const std::vector<seek>& seeks() const { return m_seeks; }
1250
+ inline const std::vector<seek>& seeks() const { return m_seeks; }
1251
+ inline short stat() const { return m_stat; };
1252
+ inline void setStat(short v) { m_stat = v; }
1253
+
1254
+ // convert for table stat
1255
+ inline short translateStat() const
1256
+ {
1257
+ if ((m_stat == STATUS_LIMMIT_OF_REJECT) ||
1258
+ (m_stat == STATUS_REACHED_FILTER_COND))
1259
+ return STATUS_EOF;
1260
+ else
1261
+ return m_stat;
1262
+ }
1263
+
1264
+ /* A special situation that if rejectCount() == 0 and status =
1265
+ STATUS_LIMMIT_OF_REJECT
1266
+ then it continues . */
1267
+ inline bool isStatContinue() const
1268
+ {
1269
+ if ((m_stat == 0) ||
1270
+ ((m_stat == STATUS_LIMMIT_OF_REJECT) && (rejectCount() == 0)))
1271
+ return true;
1272
+ return false;
1273
+ }
1274
+
1275
+ bool checkFindDirection(ushort_td op)
1276
+ {
1277
+ bool ret;
1278
+ if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI))
1279
+ ret = (direction() == table::findBackForword);
1280
+ else
1281
+ ret = (direction() == table::findForword);
1282
+ assert(ret == true);
1283
+ return ret;
1284
+ }
1285
+
1286
+ bool setDirectionByOp(short op)
1287
+ {
1288
+ bool v = ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI) ||
1289
+ (op == TD_POS_PREV_MULTI));
1290
+ return setDirection(v ? table::findBackForword : table::findForword);
1291
+ }
1292
+
1293
+ static filter* create(table* tb)
1294
+ {
1295
+ return new filter(tb);
1296
+ }
1297
+
1298
+ static void release(filter* p){ delete p; }
1299
+
923
1300
  };
924
1301
 
925
1302
  } // namespace client