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