transactd 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BUILD_UNIX-JA +6 -6
- data/README +16 -16
- data/README-JA +16 -16
- data/bin/common/tdclc_32_2_1.dll +0 -0
- data/bin/common/tdclc_64_2_1.dll +0 -0
- data/build/common/transactd_cl_common.cmake +0 -1
- data/build/common/transactd_common.cmake +28 -38
- data/build/swig/ruby/ruby.swg +36 -30
- data/build/swig/ruby/tdclrb_wrap.cpp +35016 -0
- data/build/swig/tdcl.i +217 -62
- data/build/tdclc/CMakeLists.txt +14 -26
- data/build/tdclc/libtdclcm.map +4 -0
- data/build/tdclc/tdclc.cbproj +1 -1
- data/build/tdclc/tdclc.rc +0 -0
- data/build/tdclcpp/CMakeLists.txt +7 -22
- data/build/tdclcpp/tdclcpp.rc +0 -0
- data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
- data/build/tdclrb/CMakeLists.txt +7 -49
- data/build/tdclrb/tdclrb.rc +62 -0
- data/source/bzs/db/blobBuffer.h +5 -0
- data/source/bzs/db/blobStructs.h +2 -0
- data/source/bzs/db/engine/mysql/IReadRecords.h +9 -0
- data/source/bzs/db/engine/mysql/database.cpp +391 -169
- data/source/bzs/db/engine/mysql/database.h +178 -40
- data/source/bzs/db/engine/mysql/dbManager.cpp +45 -3
- data/source/bzs/db/engine/mysql/dbManager.h +3 -39
- data/source/bzs/db/engine/mysql/errorMessage.cpp +11 -7
- data/source/bzs/db/engine/mysql/errorMessage.h +1 -1
- data/source/bzs/db/engine/mysql/mydebuglog.cpp +1 -2
- data/source/bzs/db/engine/mysql/mysqlInternal.h +8 -8
- data/source/bzs/db/engine/mysql/mysqlThd.cpp +11 -0
- data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/activeTable.cpp +41 -6
- data/source/bzs/db/protocol/tdap/client/activeTable.h +177 -8
- data/source/bzs/db/protocol/tdap/client/activeTableImple.h +141 -62
- data/source/bzs/db/protocol/tdap/client/client.cpp +39 -35
- data/source/bzs/db/protocol/tdap/client/client.h +52 -25
- data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +17 -0
- data/source/bzs/db/protocol/tdap/client/connectionPool.h +1 -0
- data/source/bzs/db/protocol/tdap/client/database.cpp +5 -1
- data/source/bzs/db/protocol/tdap/client/database.h +1 -1
- data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +49 -12
- data/source/bzs/db/protocol/tdap/client/databaseManager.h +42 -5
- data/source/bzs/db/protocol/tdap/client/dbDef.cpp +4 -2
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +71 -41
- data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +49 -49
- data/source/bzs/db/protocol/tdap/client/field.cpp +22 -13
- data/source/bzs/db/protocol/tdap/client/field.h +7 -3
- data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +0 -1
- data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +1 -0
- data/source/bzs/db/protocol/tdap/client/fields.h +111 -24
- data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/filter.h +687 -310
- data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +12 -4
- data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/memRecord.cpp +190 -32
- data/source/bzs/db/protocol/tdap/client/memRecord.h +64 -22
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +4 -4
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -2
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +6 -3
- data/source/bzs/db/protocol/tdap/client/nsTable.h +1 -1
- data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +19 -8
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +194 -87
- data/source/bzs/db/protocol/tdap/client/request.h +84 -26
- data/source/bzs/db/protocol/tdap/client/stringConverter.h +22 -12
- data/source/bzs/db/protocol/tdap/client/table.cpp +494 -286
- data/source/bzs/db/protocol/tdap/client/table.h +48 -5
- data/source/bzs/db/protocol/tdap/client/trdboostapi.h +133 -87
- data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +22 -22
- data/source/bzs/db/protocol/tdap/client/trdormapi.h +43 -18
- data/source/bzs/db/protocol/tdap/client/trnsctcl.def +3 -3
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +1 -0
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +268 -74
- data/source/bzs/db/protocol/tdap/mysql/request.h +4 -4
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +179 -43
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +4 -4
- data/source/bzs/db/protocol/tdap/tdapRequest.h +15 -14
- data/source/bzs/db/protocol/tdap/tdapSchema.h +125 -90
- data/source/bzs/db/protocol/tdap/tdapcapi.h +46 -5
- data/source/bzs/db/transactd/appModule.h +1 -1
- data/source/bzs/db/transactd/connManager.cpp +2 -0
- data/source/bzs/db/transactd/transactd.cpp +1 -0
- data/source/bzs/env/compiler.h +10 -0
- data/source/bzs/env/mbcswchrLinux.cpp +42 -6
- data/source/bzs/env/mbcswchrLinux.h +40 -12
- data/source/bzs/example/queryData.cpp +33 -4
- data/source/bzs/netsvc/client/iconnection.h +107 -0
- data/source/bzs/netsvc/client/tcpClient.cpp +15 -1
- data/source/bzs/netsvc/client/tcpClient.h +96 -87
- data/source/bzs/netsvc/server/serverCpt.cpp +5 -6
- data/source/bzs/rtl/benchmark.cpp +2 -2
- data/source/bzs/rtl/stringBuffers.cpp +3 -3
- data/source/bzs/rtl/stringBuffers.h +2 -2
- data/source/bzs/test/tdclatl/bench_query_atl.js +92 -99
- data/source/bzs/test/tdclatl/test_query_atl.js +224 -115
- data/source/bzs/test/tdclphp/bench.php +126 -101
- data/source/bzs/test/tdclphp/transactd_Test.php +1122 -158
- data/source/bzs/test/tdclrb/bench_tdclcpp.rb +12 -14
- data/source/bzs/test/tdclrb/transactd_spec.rb +1127 -142
- data/source/bzs/test/transactdBench/query_bench.cpp +32 -15
- data/source/bzs/test/transactdBench/scaling_bench.cpp +32 -7
- data/source/bzs/test/transactdBench/transactdBench.cpp +1 -1
- data/source/bzs/test/transactdBench/workerBase.h +46 -0
- data/source/bzs/test/transactdBench/workerMySQLImple.h +15 -7
- data/source/bzs/test/transactdBench/workerTransactdImple.h +10 -18
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +1487 -174
- data/source/global/ormsrcgen/main.cpp +2 -0
- data/source/global/tdclatl/Database.cpp +2 -2
- data/source/global/tdclatl/Database.h +1 -1
- data/source/global/tdclatl/FieldDefs.cpp +0 -3
- data/source/global/tdclatl/PooledDbManager.cpp +2 -2
- data/source/global/tdclatl/PooledDbManager.h +1 -1
- data/source/global/tdclatl/PreparedQuery.cpp +53 -0
- data/source/global/tdclatl/PreparedQuery.h +61 -0
- data/source/global/tdclatl/QueryBase.cpp +2 -1
- data/source/global/tdclatl/QueryBase.h +1 -1
- data/source/global/tdclatl/Record.cpp +3 -15
- data/source/global/tdclatl/Recordset.cpp +15 -10
- data/source/global/tdclatl/Recordset.h +3 -0
- data/source/global/tdclatl/Table.cpp +42 -7
- data/source/global/tdclatl/Table.h +3 -1
- data/source/global/tdclatl/activeTable.cpp +264 -76
- data/source/global/tdclatl/activeTable.h +12 -3
- data/source/global/tdclatl/tdclatl.idl +92 -10
- data/source/linux/charsetConvert.h +7 -7
- data/transactd.gemspec +14 -27
- metadata +18 -27
- data/bin/common/tdclc_32_2_0.dll +0 -0
- data/bin/common/tdclc_64_2_0.dll +0 -0
- data/build/swig/php/generate.cmake.in +0 -56
- data/build/swig/php/generate.cmd.in +0 -47
- data/build/swig/php/php.swg +0 -197
- data/build/swig/php/transactd.no_yield.php +0 -4494
- data/build/swig/php/transactd.no_yield.php.git.patch +0 -685
- data/build/swig/php/transactd.no_yield.php.patch +0 -685
- data/build/swig/php/transactd.yield.php +0 -4461
- data/build/swig/php/transactd.yield.php.git.patch +0 -652
- data/build/swig/php/transactd.yield.php.patch +0 -652
- data/build/swig/ruby/generate.cmake.in +0 -35
- data/build/swig/ruby/generate.cmd.in +0 -19
- data/build/tdclc/BUILDNUMBER.txt +0 -1
- data/build/tdclcpp/BUILDNUMBER.txt +0 -1
- data/build/tdclrb/BUILDNUMBER.txt +0 -1
- data/build/tdclrb/GEM_RELEASE_VERSION +0 -1
@@ -36,22 +36,10 @@ namespace tdap
|
|
36
36
|
namespace client
|
37
37
|
{
|
38
38
|
|
39
|
-
|
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
|
-
|
176
|
+
|
177
|
+
unsigned char* writeBuffer(unsigned char* p)
|
102
178
|
{
|
103
179
|
int n = sizeof(resultField);
|
104
|
-
|
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
|
197
|
+
unsigned char* writeBuffer(unsigned char* p)
|
121
198
|
{
|
122
199
|
int n = sizeof(resultDef);
|
123
|
-
|
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
|
-
|
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 (
|
151
|
-
|
152
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
282
|
+
int size() const
|
180
283
|
{
|
181
|
-
return
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
343
|
+
template <class T>
|
344
|
+
void setValue(table* tb, const T value)
|
221
345
|
{
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
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
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
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 && (
|
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
|
-
|
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,
|
384
|
+
ret = setCompFiled(tb, value); // value is field name
|
251
385
|
else
|
252
386
|
{
|
253
|
-
|
254
|
-
|
255
|
-
|
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
|
396
|
+
unsigned char* writeBuffer(unsigned char* p, bool end, bool preparingMode) const
|
265
397
|
{
|
266
|
-
int n =
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
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
|
-
|
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
|
-
|
297
|
-
|
298
|
-
|
299
|
-
memcpy(
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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,
|
526
|
+
unsigned char* writeBuffer(unsigned char* p, unsigned short prepareId) const
|
391
527
|
{
|
392
528
|
int n = sizeof(header);
|
393
|
-
|
394
|
-
|
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
|
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
|
-
|
546
|
+
autoBackup(table* tb, std::vector<char>& b):m_tb(tb),
|
547
|
+
m_len(m_tb->tableDef()->maxRecordLen)
|
408
548
|
{
|
409
|
-
|
410
|
-
|
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
|
-
~
|
554
|
+
~autoBackup()
|
414
555
|
{
|
415
|
-
memcpy(m_tb->fieldPtr(0), m_buf,
|
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
|
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
|
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
|
-
|
433
|
-
|
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
|
-
|
440
|
-
|
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
|
-
|
449
|
-
r
|
450
|
-
r
|
451
|
-
|
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
|
-
|
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
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
689
|
+
uchar_td* reallocSeeksDataBuffer(size_t size)
|
519
690
|
{
|
520
|
-
|
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
|
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
|
-
|
526
|
-
|
527
|
-
|
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
|
-
|
530
|
-
|
531
|
-
|
532
|
-
ushort_td len =
|
533
|
-
|
534
|
-
|
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
|
-
|
539
|
-
bool
|
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
|
542
|
-
|
543
|
-
|
544
|
-
|
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
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
if (
|
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
|
-
|
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
|
-
|
563
|
-
|
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(
|
764
|
+
m_seeks.resize(size / keySize);
|
566
765
|
int maxKeylen = 0;
|
567
|
-
for (int j = 0; 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
|
-
|
573
|
-
|
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
|
-
|
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
|
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
|
-
|
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 =
|
871
|
+
for (size_t i = m_seeksLimitIndex - 1; i >= m_seeksWritedCount; --i)
|
736
872
|
{
|
737
|
-
cutsize += (int)m_seeks[i
|
873
|
+
cutsize += (int)m_seeks[i].size(m_isTransactd);
|
738
874
|
if (oversize - cutsize < 0)
|
739
875
|
{
|
740
|
-
|
876
|
+
m_seeksLimitIndex = i;
|
741
877
|
return cutsize;
|
742
878
|
}
|
743
879
|
}
|
744
880
|
return 0;
|
745
881
|
}
|
746
882
|
|
747
|
-
|
883
|
+
// Calc send buffer size and set last index of seeksMode can sent (m_seeksLimitIndex).
|
884
|
+
int calcSendBuflen()
|
748
885
|
{
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
if (len > maxDataBuffer())
|
886
|
+
int len = m_hd.size();
|
887
|
+
|
888
|
+
if (!m_preparedId)
|
753
889
|
{
|
754
|
-
|
755
|
-
|
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
|
-
|
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
|
-
|
760
|
-
int resultLen = (int)resultBufferNeedSize();
|
761
|
-
if (resultLen > maxDataBuffer())
|
915
|
+
else
|
762
916
|
{
|
763
|
-
|
764
|
-
|
765
|
-
|
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
|
-
|
769
|
-
|
770
|
-
|
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->
|
934
|
+
m_extendBuflen += m_tb->tableDef()->maxRecordLen;
|
935
|
+
m_tb->reallocDataBuffer(m_ddba ? len : m_extendBuflen);
|
936
|
+
return true;
|
937
|
+
}
|
773
938
|
|
774
|
-
|
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
|
-
|
777
|
-
|
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
|
-
|
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),
|
785
|
-
|
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() {
|
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
|
-
|
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->
|
1167
|
+
return m_extendBuflen - m_tb->tableDef()->maxRecordLen;
|
855
1168
|
return m_extendBuflen;
|
856
1169
|
}
|
857
1170
|
|
858
|
-
|
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]
|
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]
|
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]
|
1198
|
+
return m_fields[index].pos;
|
888
1199
|
}
|
889
1200
|
|
890
1201
|
bool writeBuffer()
|
891
1202
|
{
|
892
|
-
|
893
|
-
|
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]
|
902
|
-
(m_fields[0]
|
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
|
-
|
918
|
-
|
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
|