transactd 1.1.2 → 1.2.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +37 -4
  3. data/bin/common/tdclc_32_1_2.dll +0 -0
  4. data/bin/common/tdclc_64_1_2.dll +0 -0
  5. data/build/common/transactd_cl_common.cmake +0 -1
  6. data/build/common/transactd_common.cmake +26 -6
  7. data/build/swig/php/generate.cmake.in +58 -0
  8. data/build/swig/php/generate.cmd.in +41 -0
  9. data/build/swig/php/php.swg +155 -0
  10. data/build/swig/ruby/ruby.swg +38 -0
  11. data/build/swig/tdcl.i +133 -3
  12. data/build/tdclc/CMakeLists.txt +4 -1
  13. data/build/tdclc/tdclc_32.cbproj +1 -1
  14. data/build/tdclc/tdclc_64.cbproj +1 -1
  15. data/build/tdclcpp/CMakeLists.txt +1 -1
  16. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +1 -4
  17. data/build/tdclcpp/tdclcpp_bcb_64.cbproj +0 -3
  18. data/build/tdclrb/CMakeLists.txt +1 -1
  19. data/build/tdclrb/GEM_VERSION +2 -2
  20. data/source/bzs/db/engine/mysql/IReadRecords.h +1 -1
  21. data/source/bzs/db/engine/mysql/bookmark.h +3 -3
  22. data/source/bzs/db/engine/mysql/database.cpp +95 -19
  23. data/source/bzs/db/engine/mysql/database.h +6 -6
  24. data/source/bzs/db/engine/mysql/mysqlInternal.h +43 -1
  25. data/source/bzs/db/engine/mysql/mysqlThd.cpp +10 -8
  26. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
  27. data/source/bzs/db/protocol/tdap/btrDate.h +2 -2
  28. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +15 -8
  29. data/source/bzs/db/protocol/tdap/client/dbDef.h +2 -2
  30. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +4 -0
  31. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +0 -5
  32. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +0 -4
  33. data/source/bzs/db/protocol/tdap/client/filter.cpp +0 -484
  34. data/source/bzs/db/protocol/tdap/client/filter.h +696 -84
  35. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +13 -3
  36. data/source/bzs/db/protocol/tdap/client/nsTable.h +12 -6
  37. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -1
  38. data/source/bzs/db/protocol/tdap/client/stringConverter.h +1 -0
  39. data/source/bzs/db/protocol/tdap/client/table.cpp +519 -75
  40. data/source/bzs/db/protocol/tdap/client/table.h +49 -7
  41. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +145 -124
  42. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +39 -0
  43. data/source/bzs/db/protocol/tdap/client/trdormapi.h +872 -0
  44. data/source/bzs/db/protocol/tdap/myDateTime.cpp +8 -8
  45. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +7 -9
  46. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +406 -195
  47. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +64 -13
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +2 -1
  49. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +35 -3
  50. data/source/bzs/db/protocol/tdap/tdapSchema.h +11 -3
  51. data/source/bzs/db/protocol/tdap/tdapcapi.h +63 -53
  52. data/source/bzs/env/crosscompile.h +8 -3
  53. data/source/bzs/example/connection_pool_c.cpp +1 -7
  54. data/source/bzs/example/useORM.cpp +585 -0
  55. data/source/bzs/rtl/exception.h +6 -0
  56. data/source/bzs/test/tdclatl/bench_tdclatl.js +12 -7
  57. data/source/bzs/test/tdclphp/transactd_Test.php +1845 -0
  58. data/source/bzs/test/tdclphp/transactd_blob_Test.php +325 -0
  59. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +183 -0
  60. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +212 -0
  61. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +332 -0
  62. data/source/bzs/test/tdclrb/transactd_spec.rb +256 -1
  63. data/source/bzs/test/trdclengn/test_blob.cpp +327 -0
  64. data/source/bzs/test/trdclengn/test_trdclengn.cpp +485 -5
  65. data/source/global/tdclatl/QueryBase.cpp +231 -0
  66. data/source/global/tdclatl/QueryBase.h +96 -0
  67. data/source/global/tdclatl/Table.cpp +24 -0
  68. data/source/global/tdclatl/Table.h +2 -1
  69. data/source/global/tdclatl/resource.h +0 -0
  70. data/source/global/tdclatl/tdclatl.idl +88 -2
  71. metadata +16 -3
  72. data/bin/common/tdclc_32_1_1.dll +0 -0
  73. data/bin/common/tdclc_64_1_1.dll +0 -0
@@ -19,6 +19,11 @@
19
19
  02111-1307, USA.
20
20
  ================================================================= */
21
21
  #include "table.h"
22
+ #include <assert.h>
23
+ #include <vector>
24
+ #include <boost/algorithm/string.hpp>
25
+ #include <boost/tokenizer.hpp>
26
+
22
27
 
23
28
  namespace bzs
24
29
  {
@@ -31,120 +36,727 @@ namespace tdap
31
36
  namespace client
32
37
  {
33
38
 
39
+ #define BOOKMARK_ALLOC_SIZE 40960
40
+ #define BOOKMARK_SIZE 4
41
+ #define DATASIZE_BYTE 2
42
+
43
+ #define MAX_DATA_SIZE 57000
44
+
45
+
46
+ inline ushort_td varlenForFilter(const fielddef& fd)
47
+ {
48
+ if (((fd.type >= ft_myvarchar) && (fd.type <= ft_mywvarbinary)) || fd.type == ft_lstring)
49
+ return fd.len < 256 ? 1 : 2;
50
+ else if ((fd.type == ft_myblob) || (fd.type == ft_mytext))
51
+ return fd.len - 8;
52
+ return 0;
53
+ }
54
+
55
+ /** Length of compare
56
+ * if part of string or zstring then return strlen.
57
+ */
58
+ inline uint_td compDataLen(const fielddef& fd, const uchar_td* ptr, bool part)
59
+ {
60
+ uint_td length = fd.keyDataLen(ptr);
61
+ if (part)
62
+ {
63
+ if ((fd.type == ft_string) || (fd.type == ft_zstring) || (fd.type == ft_note))
64
+ length = (uint_td)strlen((const char*)ptr);
65
+ else if ((fd.type == ft_wstring) || (fd.type == ft_wzstring))
66
+ length = (uint_td)wcslen((const wchar_t*)ptr);
67
+ }
68
+ return length;
69
+ }
70
+
71
+ bool verType(uchar_td type)
72
+ {
73
+ if (((type >= ft_myvarchar) && (type <= ft_mywvarbinary)) || type == ft_lstring)
74
+ return true;
75
+ return false;
76
+ }
77
+
34
78
 
35
79
  #pragma option -a-
36
80
  pragma_pack1
37
81
 
38
- struct BFilter
82
+ struct resultField
39
83
  {
40
- uchar_td Type;
41
- ushort_td Len;
42
- ushort_td Pos;
43
- uchar_td CompType;
44
- uchar_td LogicalType;
45
- ushort_td Data;
84
+ unsigned short len;
85
+ unsigned short pos;
86
+
87
+ bool setParam(table* tb, const _TCHAR* name)
88
+ {
89
+ short fieldNum = tb->fieldNumByName(name);
90
+ if (fieldNum != -1)
91
+ {
92
+ fielddef* fd = &tb->tableDef()->fieldDefs[fieldNum];
93
+ len = fd->len;
94
+ pos = fd->pos;
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ unsigned char* writeBuffer(unsigned char* p, bool estimate)
100
+ {
101
+ int n = sizeof(resultField);
102
+ if (!estimate) memcpy(p, this, n);
103
+ return p+n;
104
+ }
46
105
  };
47
106
 
48
- struct BFilterHeader
107
+ struct resultDef
49
108
  {
50
- ushort_td BufLen;
51
- char PosType[2]; // "EG" or "UC"
52
- ushort_td RejectCount;
53
- ushort_td LogicalCount;
109
+ resultDef()
110
+ {
111
+ reset();
112
+ }
113
+ void reset()
114
+ {
115
+ maxRows = 0;
116
+ fieldCount = 0;
117
+ }
118
+ unsigned short maxRows;
119
+ unsigned short fieldCount;
120
+ unsigned char* writeBuffer(unsigned char* p, bool estimate)
121
+ {
122
+ int n = sizeof(resultDef);
123
+ if (!estimate) memcpy(p, this, n);
124
+ return p + n;
125
+ }
126
+ friend class filter;
54
127
  };
55
128
 
56
- struct BSelectField
129
+ struct logic
57
130
  {
58
- ushort_td iFieldLen;
59
- ushort_td iFieldOffset;
131
+ unsigned char type;
132
+ unsigned short len;
133
+ unsigned short pos;
134
+ unsigned char logType;
135
+ char opr;
136
+ unsigned char* data;
137
+
138
+ public:
139
+ logic():data(NULL){}
140
+
141
+ ~logic()
142
+ {
143
+ delete [] data;
144
+ }
145
+
146
+ size_t getLength()
147
+ {
148
+ return sizeof(logic) - sizeof(unsigned char*) + getDatalen();
149
+ }
150
+
151
+ void setFieldParam(fielddef* fd )
152
+ {
153
+ type = fd->type;
154
+ len = fd->len;
155
+ pos = fd->pos;
156
+ }
157
+
158
+ int getDatalen() const
159
+ {
160
+ if (logType & 64)
161
+ return 2;
162
+ return len;
163
+ }
164
+
165
+ bool setCompFiled(table* tb, short index, const _TCHAR* name)
166
+ {
167
+ short tmp = tb->fieldNumByName(name);
168
+ if (tmp !=-1)
169
+ {
170
+ memcpy(data, &tmp, 2);
171
+ logType |= CMPLOGICAL_FIELD;
172
+ return true;
173
+ }
174
+ return false;
175
+ }
176
+
177
+ bool isPart(table* tb, short index)
178
+ {
179
+ fielddef* fd = &tb->tableDef()->fieldDefs[index];
180
+ bool ret = false;
181
+ if (fd->isStringType())
182
+ {
183
+ _TCHAR* p = (_TCHAR*)tb->getFVstr(index);
184
+ if (p)
185
+ {
186
+ size_t n = _tcslen(p);
187
+ if ((ret = (p[n-1] == _T('*')))!=0)
188
+ {
189
+ p[n-1] = 0x00;
190
+ tb->setFV(index, p);
191
+ }
192
+ }else
193
+ tb->setFV(index, _T(""));
194
+ }
195
+ return ret;
196
+ }
197
+
198
+ void allocBuffer(int size)
199
+ {
200
+ if (data)
201
+ delete [] data;
202
+ data = new unsigned char[size + 2];
203
+ memset(data, 0, size + 2);
204
+ }
205
+
206
+ void copyToBuffer(table* tb, short index, bool part)
207
+ {
208
+ fielddef* fd = &tb->tableDef()->fieldDefs[index];
209
+ const uchar_td* ptr = (const uchar_td*)tb->fieldPtr(index);
210
+ int varlen = varlenForFilter(*fd);
211
+ int copylen = compDataLen(*fd, ptr, part);
212
+ len = varlen + copylen;
213
+ allocBuffer(len);
214
+ uchar_td* to = (uchar_td*)data;
215
+ if (varlen)
216
+ memcpy(to, ptr, varlen);
217
+ memcpy(to + varlen, fd->keyData(ptr), copylen);
218
+
219
+ if (!part && (fd->varLenBytes() || fd->blobLenBytes()))
220
+ logType |= CMPLOGICAL_VAR_COMP_ALL; //match complate
221
+ }
222
+
223
+ bool setParam(table* tb, const _TCHAR* name
224
+ , const _TCHAR* type, const _TCHAR* value, char combine, bool compField = false)
225
+ {
226
+ logType = getFilterLogicTypeCode(type);
227
+ opr = combine;
228
+ short fieldNum = tb->fieldNumByName(name);
229
+ if ((logType!=255) && (fieldNum != -1))
230
+ {
231
+ bool ret = true;
232
+ fielddef* fd = &tb->tableDef()->fieldDefs[fieldNum];
233
+ setFieldParam(fd);
234
+ unsigned char* tmp = new unsigned char[len];
235
+
236
+ //backup
237
+ memcpy(tmp, tb->fieldPtr(fieldNum), len);
238
+
239
+ if (compField)
240
+ ret = setCompFiled(tb, fieldNum, value);// value is field name
241
+ else
242
+ {
243
+ tb->setFV(fieldNum, value);
244
+ bool part = isPart(tb, fieldNum);
245
+ copyToBuffer(tb, fieldNum, part);
246
+ }
247
+ //restore
248
+ memcpy(tb->fieldPtr(fieldNum),tmp, len);
249
+ delete [] tmp;
250
+ return ret;
251
+ }
252
+ return false;
253
+ }
254
+
255
+ //setParam from keyValue
256
+ bool setParam(void* keyValue, ushort_td keylen)
257
+ {
258
+ logType = 1;// '=' type
259
+ opr = eCor;
260
+ len = keylen;
261
+ type = ft_string;// this value is ignored.
262
+ pos = 0;
263
+ allocBuffer(len);
264
+ memcpy(data, keyValue, len);
265
+ return true;
266
+ }
267
+
268
+ unsigned char* writeBuffer(unsigned char* p, bool estimate, bool end)
269
+ {
270
+ int n = sizeof(logic) - sizeof(unsigned char*);
271
+ if (!estimate)
272
+ {
273
+ memcpy(p, this, n);
274
+ if (end)
275
+ *(p+n-1) = eCend;
276
+ }
277
+ p += n;
278
+
279
+ n = getDatalen();
280
+ if (!estimate) memcpy(p, data, n);
281
+ return p + n;
282
+ }
283
+
284
+ bool canJoin(bool after)
285
+ {
286
+ bool flag = true;
287
+ if (after)
288
+ flag = (opr == 1);
289
+ return (flag
290
+ && (logType == 1)
291
+ && (type != ft_zstring)
292
+ && !verType(type));
293
+ }
294
+
295
+ bool isNextFiled(logic* src)
296
+ {
297
+ return ((pos + len) == src->pos);
298
+ }
299
+
300
+ void joinAfter(logic* src)
301
+ {
302
+ assert(src);
303
+ assert(src->data);
304
+ unsigned char* tmp = data;
305
+ data = new unsigned char[len + src->len + 2];
306
+ memcpy(data, tmp, len);
307
+ memcpy(data + len, src->data, src->len);
308
+ len += src->len;
309
+ type = ft_string; //compare by memcmp
310
+ opr = src->opr;
311
+ delete [] tmp;
312
+ }
60
313
  };
61
314
 
62
- struct BFilterDisc
315
+ struct header
63
316
  {
64
- ushort_td iRecordCount;
65
- ushort_td iFieldCount;
66
- BSelectField iSelectFields[255];
317
+ unsigned short len;
318
+ char type[2];
319
+ unsigned short rejectCount;
320
+ unsigned short logicalCount;
321
+ header(){reset();};
322
+ void reset()
323
+ {
324
+ rejectCount = 1;
325
+ logicalCount = 0;
326
+ len = 0;
327
+ setPositionType(true);
328
+ }
329
+
330
+ void setPositionType(bool incCurrent)
331
+ {
332
+ if (incCurrent)
333
+ {
334
+ type[0] = 'U';
335
+ type[1] = 'C';
336
+ }
337
+ else
338
+ {
339
+ type[0] = 'E';
340
+ type[1] = 'G';
341
+ }
342
+ }
343
+
344
+ bool positionTypeNext() const
345
+ {
346
+ return (type[0] == 'E');
347
+ }
348
+
349
+ unsigned char* writeBuffer(unsigned char* p, bool estimate)
350
+ {
351
+ int n = sizeof(header);
352
+ if (!estimate) memcpy(p, this, n);
353
+ return p + n;
354
+ }
67
355
  };
68
-
69
356
  #pragma option -a
70
357
  pragma_pop
71
358
 
359
+
360
+
72
361
  class filter
73
362
  {
74
363
 
75
364
  table* m_tb;
76
-
77
- //buffer
78
- _TCHAR* m_pFilter;
79
- void* m_pEntendBuf;
80
- ushort_td m_pEntendBuflen;
81
- uint_td m_ExDataBufLen;
82
-
83
- //hedaer
84
- ushort_td m_RejectCount;
85
- char m_PosType[3]; // "EG" or "UC"
86
-
87
- //tail
88
- ushort_td m_iRecordCount;
89
- ushort_td m_iFieldCount;
90
-
91
- ushort_td* m_iRecordCountDirect;
92
- //result
93
- ushort_td m_iFieldLen[255];
94
- ushort_td m_iFieldOffset[255];
95
-
96
- bool GetCompStr(_TCHAR** str);
97
- uchar_td GetLogical(_TCHAR** str);
98
- uchar_td GetCompType(_TCHAR** str);
99
- short GetField(_TCHAR** str);
100
- ushort_td GetFieldLen(int index);
101
- ushort_td GetFieldOffset(int index);
102
- bool MakeFieldSelect(_TCHAR** str);
103
-
104
- bool m_FieldSelected;
365
+ header m_hd;
366
+ resultDef m_ret;
367
+ std::vector<resultField*> m_fields;
368
+ std::vector<logic*> m_logics;
369
+ int m_extendBuflen;
370
+ std::_tstring m_str;
371
+ bool m_ignoreFields;
372
+ bool m_seeksMode;
373
+ bool m_useOptimize;
374
+ size_t m_seeksWritedCount;
375
+ size_t m_logicalLimitCount;
376
+ table::eFindType m_direction;
377
+ std::vector<std::_tstring> m_keyValuesCache;
378
+
379
+ bool addWhere(const _TCHAR* name, const _TCHAR* type, const _TCHAR* value, char combine, bool compField = false)
380
+ {
381
+ logic* l = new logic();
382
+ if (l->setParam(m_tb, name, type, value, combine, compField))
383
+ {
384
+ m_logics.push_back(l);
385
+ return true;
386
+ }
387
+ delete l;
388
+ return false;
389
+ }
390
+
391
+ void addAllFields()
392
+ {
393
+ resultField* r = new resultField();
394
+ r->len = (ushort_td) m_tb->tableDef()->maxRecordLen;
395
+ r->pos = 0;
396
+ m_fields.push_back(r);
397
+ }
398
+
399
+ bool addSelect(const _TCHAR* name)
400
+ {
401
+ resultField* r = new resultField();
402
+ if (r->setParam(m_tb, name))
403
+ {
404
+ m_fields.push_back(r);
405
+ return true;
406
+ }
407
+ delete r;
408
+ return false;
409
+ }
410
+
411
+ bool setSelect(const std::vector<std::_tstring>& selects)
412
+ {
413
+ for (size_t i=0;i < selects.size();++i)
414
+ {
415
+ if (!addSelect(selects[i].c_str()))
416
+ return false;
417
+ }
418
+ return true;
419
+ }
420
+
421
+ bool setWhere(const std::vector<std::_tstring>& where)
422
+ {
423
+ if (where.size() == 0) return true;
424
+ if (where.size() < 3) return false;
425
+
426
+ for (size_t i=0;i<where.size();i+=4)
427
+ {
428
+ char combine = eCend;
429
+ std::_tstring value = where[i+2];
430
+ bool compField = (value[0] == _T('['));
431
+ if (compField)
432
+ {
433
+ value.erase(value.begin());
434
+ value.erase(value.end() - 1);
435
+ }
436
+ if (i+3 < where.size())
437
+ {
438
+ std::_tstring s = where[i+3];
439
+ boost::algorithm::to_lower(s);
440
+ if (s == _T("or")) combine = eCor;
441
+ else if (s == _T("and"))
442
+ combine = eCand;
443
+ else
444
+ return false;
445
+ }
446
+ if (!addWhere(where[i].c_str(), where[i+1].c_str()
447
+ , value.c_str(), combine, compField))
448
+ return false;
449
+ }
450
+ return true;
451
+
452
+ }
453
+
454
+
455
+ bool setSeeks(const std::vector<std::_tstring>& keyValues)
456
+ {
457
+ //Check key values
458
+ keydef* kd = &m_tb->tableDef()->keyDefs[m_tb->keyNum()];
459
+ if (keyValues.size() % kd->segmentCount)
460
+ return false;
461
+ //Check uniqe key
462
+ if (kd->segments[0].flags.bit0)
463
+ return false;
464
+
465
+ m_keyValuesCache = keyValues;
466
+ for (size_t i=0;i<keyValues.size();i+= kd->segmentCount)
467
+ {
468
+ for (int j=0;j<kd->segmentCount;++j)
469
+ m_tb->setFV(kd->segments[j].fieldNum, keyValues[i+j].c_str());
470
+
471
+ logic* l = new logic();
472
+ ushort_td len = m_tb->writeKeyData();
473
+ if (l->setParam(m_tb->m_keybuf, len))
474
+ m_logics.push_back(l);
475
+ else
476
+ {
477
+ delete l;
478
+ return false;
479
+ }
480
+ }
481
+ if (m_logics.size())
482
+ m_logics[m_logics.size() -1]->opr = eCend;
483
+ m_seeksMode = true;
484
+ m_seeksWritedCount = 0;
485
+ return true;
486
+ }
487
+
488
+ bool doSetFilter(const queryBase* q)
489
+ {
490
+ cleanup();
491
+ setRejectCount(q->getReject());
492
+ setMaxRows(q->getLimit());
493
+ m_direction = q->getDirection();
494
+ m_useOptimize = q->isOptimize();
495
+
496
+ if (q->isAll())
497
+ addAllFields();
498
+ else
499
+ {
500
+ if (q->getSelects().size() == 0)
501
+ addAllFields();
502
+ else if (!setSelect(q->getSelects()))
503
+ return false;
504
+
505
+ //seeks or where
506
+ if (q->getSeekKeyValues().size() && q->getWheres().size())
507
+ return false;
508
+
509
+ if (q->getSeekKeyValues().size())
510
+ return setSeeks(q->getSeekKeyValues());
511
+ else if (q->getWheres().size())
512
+ return setWhere(q->getWheres());
513
+ }
514
+ return true;
515
+ }
516
+
517
+ ushort_td resultRowSize(bool ignoreFields)
518
+ {
519
+
520
+ ushort_td recordLen = BOOKMARK_SIZE + DATASIZE_BYTE;
521
+ if (!ignoreFields)
522
+ {
523
+ for (size_t i=0;i< m_fields.size();++i)
524
+ recordLen += m_fields[i]->len;
525
+ }
526
+ return recordLen;
527
+ }
528
+
529
+ ushort_td calcMaxRows()
530
+ {
531
+ return (ushort_td)(MAX_DATA_SIZE / resultRowSize(m_ignoreFields));
532
+ }
533
+
534
+ ushort_td resultBufferNeedSize()
535
+ {
536
+ return (m_ret.maxRows * resultRowSize(m_ignoreFields)) + DATASIZE_BYTE;
537
+ }
538
+
539
+ void joinLogic()
540
+ {
541
+ if (m_seeksMode || !m_useOptimize) return;
542
+
543
+ for (int i= (int)m_logics.size()-2;i>=0;--i)
544
+ {
545
+ logic* la = m_logics[i+1];
546
+ logic* lb = m_logics[i];
547
+ if (la->canJoin(false) && lb->canJoin(true) && lb->isNextFiled(la))
548
+ {
549
+ lb->joinAfter(la);
550
+ delete la;
551
+ m_logics.erase(m_logics.begin()+i+1);
552
+ }
553
+ }
554
+ }
555
+
556
+ int doWriteBuffer(bool estimate)
557
+ {
558
+ unsigned char* p = (unsigned char*)m_tb->dataBak();
559
+ unsigned char* start = p;
560
+
561
+ m_hd.logicalCount = (ushort_td)m_logicalLimitCount;
562
+ if (m_ignoreFields)
563
+ m_ret.fieldCount = 0;
564
+ else
565
+ m_ret.fieldCount = (ushort_td)m_fields.size();
566
+
567
+ size_t first = 0, last = m_logicalLimitCount;
568
+ if (m_seeksMode)
569
+ {
570
+ first = m_seeksWritedCount;
571
+ last = std::min<size_t>(calcMaxRows() + m_seeksWritedCount, m_logicalLimitCount);
572
+ m_hd.rejectCount = 0;
573
+ m_ret.maxRows = m_hd.logicalCount = (ushort_td)(last - first);
574
+ }
575
+ if (m_ret.maxRows == 0)
576
+ m_ret.maxRows = calcMaxRows();
577
+
578
+ p = m_hd.writeBuffer(p, estimate);
579
+ for (size_t i=first;i< last;++i)
580
+ p = m_logics[i]->writeBuffer(p, estimate, (i==(last-1)));
581
+ if (m_seeksMode && !estimate)
582
+ m_seeksWritedCount += m_hd.logicalCount;
583
+
584
+ p = m_ret.writeBuffer(p, estimate);
585
+
586
+ if (!m_ignoreFields)
587
+ {
588
+ for (size_t i=0;i< m_fields.size();++i)
589
+ p = m_fields[i]->writeBuffer(p, estimate);
590
+ }
591
+
592
+ //write total length
593
+ int len = (int)(p - start);
594
+ unsigned short* s = (unsigned short*)start;
595
+ if (!estimate)
596
+ *s = len;
597
+ return len;
598
+ }
599
+
600
+ int calcLogicalCutsize(int oversize)
601
+ {
602
+ int cutsize = 0;
603
+ for (size_t i=m_hd.logicalCount-1;i!=0;--i)
604
+ {
605
+ cutsize += (int)m_logics[i+m_seeksWritedCount]->getLength();
606
+ if (oversize - cutsize < 0)
607
+ {
608
+ m_logicalLimitCount = i;
609
+ return cutsize;
610
+ }
611
+ }
612
+ return 0;
613
+ }
614
+
615
+ bool allocDataBuffer()
616
+ {
617
+ joinLogic();
618
+ m_logicalLimitCount = m_logics.size();
619
+ int len = doWriteBuffer(true);
620
+ if (len > (int)MAX_DATA_SIZE)
621
+ {
622
+ if (m_seeksMode)
623
+ len -= calcLogicalCutsize(len - MAX_DATA_SIZE + 1);
624
+ else
625
+ return false;
626
+ }
627
+ m_hd.len = len;
628
+ int resultLen = resultBufferNeedSize();
629
+ if (resultLen > MAX_DATA_SIZE)
630
+ {
631
+ m_ret.maxRows = calcMaxRows();
632
+ resultLen = resultBufferNeedSize();
633
+ }
634
+ m_extendBuflen = std::max<int>((int)m_hd.len, resultLen);
635
+ m_extendBuflen = std::max<int>(m_extendBuflen, m_tb->tableDef()->maxRecordLen);
636
+ if ((m_fields.size() != 1) || m_tb->valiableFormatType())
637
+ m_extendBuflen += m_tb->buflen();
638
+
639
+ if ((int)m_tb->buflen() < m_extendBuflen)
640
+ {
641
+ m_tb->setDataBak((void*) realloc(m_tb->dataBak(), m_extendBuflen));
642
+ m_tb->setData(m_tb->dataBak());
643
+ }
644
+ return true;
645
+ }
105
646
 
106
647
  public:
107
- filter(table* pBao);
108
- ~filter();
109
-
110
- bool posTypeNext() {return GetPosType();}
111
-
112
- void setPosTypeNext(bool v) {SetPosType(v);}
113
-
114
- uint_td exDataBufLen() const {return m_ExDataBufLen;}
115
-
116
- ushort_td recordCount() const {return m_iRecordCount;}
117
-
118
- void setRecordCount(ushort_td v) {m_iRecordCount = v;}
648
+ filter(table* tb):m_tb(tb),m_ignoreFields(false)
649
+ ,m_seeksMode(false),m_seeksWritedCount(0),m_useOptimize(true){}
650
+ ~filter()
651
+ {
652
+ cleanup();
653
+ }
654
+
655
+ void cleanup()
656
+ {
657
+ for (size_t i=0;i < m_logics.size();++i)
658
+ delete m_logics[i];
659
+ for (size_t i=0;i < m_fields.size();++i)
660
+ delete m_fields[i];
661
+ m_logics.erase(m_logics.begin(), m_logics.end());
662
+ m_fields.erase(m_fields.begin(), m_fields.end());
663
+ m_hd.reset();
664
+ m_ret.reset();
665
+ m_ignoreFields = false;
666
+ m_seeksMode = false;
667
+ m_seeksWritedCount = 0;
668
+ m_useOptimize = true;
669
+ }
670
+
671
+ bool setQuery(const queryBase* q)
672
+ {
673
+ m_str = q->toString();
674
+ bool ret = doSetFilter(q);
675
+ if (!ret)
676
+ cleanup();
677
+ return ret;
678
+ }
679
+
680
+ bool isWriteComleted() const
681
+ {
682
+ if (!m_seeksMode) return true;
683
+ return (m_seeksWritedCount == m_logics.size());
684
+ }
685
+ void resetSeeksWrited(){m_seeksWritedCount = 0;}
686
+
687
+ void setPositionType(bool incCurrent){m_hd.setPositionType(incCurrent);}
688
+
689
+ bool positionTypeNext() const{return m_hd.positionTypeNext();}
690
+
691
+ void setRejectCount(ushort_td v){m_hd.rejectCount = v;}
692
+ ushort_td rejectCount()const {return m_hd.rejectCount;}
693
+
694
+ void setMaxRows(ushort_td v){m_ret.maxRows = v;}
695
+ ushort_td maxRows()const {return m_ret.maxRows;}
696
+
697
+ ushort_td recordCount()const {return maxRows();}
698
+
699
+ void setPosTypeNext(bool v){setPositionType(!v);}
700
+
701
+ uint_td exDataBufLen() const
702
+ {
703
+ if ((m_fields.size() != 1) || m_tb->valiableFormatType())
704
+ return m_extendBuflen - m_tb->buflen();
705
+ return m_extendBuflen;
706
+ }
707
+
708
+ void init(table* pBao){};
709
+
710
+ const _TCHAR* filterStr(){return m_str.c_str();}
711
+
712
+ ushort_td fieldCount() const {return m_ret.fieldCount;}
713
+
714
+ void setFieldCount(ushort_td v){m_ret.fieldCount = v;}
715
+
716
+ ushort_td fieldLen(int index) const
717
+ {
718
+ assert(index < (int)m_fields.size());
719
+ return m_fields[index]->len;
720
+ }
721
+
722
+ ushort_td fieldOffset(int index) const
723
+ {
724
+ assert(index < (int)m_fields.size());
725
+ return m_fields[index]->pos;
726
+ }
727
+
728
+ bool writeBuffer()
729
+ {
730
+ if (allocDataBuffer())
731
+ return (doWriteBuffer(false) > 0);
732
+ return false;
733
+ }
734
+
735
+ ushort_td extendBuflen() const{return m_extendBuflen;}
736
+
737
+ bool fieldSelected() const
738
+ {
739
+ return !((m_fields.size() == 1) && (m_fields[0]->pos == 0));
740
+ }
741
+
742
+ bool ignoreFields() const {return m_ignoreFields;}
743
+
744
+ /* The Ignore fields option don't use with multi seek operation.
745
+ because if a server are not found a record then a server return
746
+ error code in a bookmark field.
747
+ */
748
+ void setIgnoreFields(bool v){m_ignoreFields = v;}
749
+ bool isSeeksMode()const {return m_seeksMode;}
750
+ table::eFindType direction() const{return m_direction;}
751
+ void setDirection(table::eFindType v) {m_direction = v;}
752
+ const std::vector<std::_tstring>& keyValuesCache(){return m_keyValuesCache;};
119
753
 
120
- ushort_td fieldCount() const {return m_iFieldCount;}
121
754
 
122
- void setFieldCount(ushort_td v) {m_iFieldCount = v;}
123
-
124
- void* entendBuf() const {return m_pEntendBuf;}
125
-
126
- void setEntendBuf(void* v) {m_pEntendBuf = v;};
127
-
128
- ushort_td* recordCountDirect() const {return m_iRecordCountDirect;}
129
-
130
- void setRecordCountDirect(ushort_td* v) {m_iRecordCountDirect = v;}
131
-
132
- ushort_td rejectCount() const {return m_RejectCount;}
133
-
134
- ushort_td fieldLen(int index) {return GetFieldLen(index);}
755
+ };
135
756
 
136
- ushort_td fieldOffset(int index) {return GetFieldOffset(index);}
137
757
 
138
- bool fieldSelected() const {return m_FieldSelected;}
139
758
 
140
- void init(table* pBao);
141
- bool GetPosType();
142
- void SetPosType(bool);
143
- void WriteBuffer();
144
- bool setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCount);
145
- _TCHAR* filterStr();
146
759
 
147
- };
148
760
 
149
761
  }// namespace client
150
762
  }// namespace tdap