transactd 2.0.1 → 2.1.0

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