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
@@ -103,15 +103,16 @@ struct joinInfo
|
|
103
103
|
|
104
104
|
#define JOIN_KEYVALUE_TYPE_PTR 0
|
105
105
|
#define JOIN_KEYVALUE_TYPE_STR 1
|
106
|
-
|
106
|
+
#define MAX_JOIN_KEY_SIZE 8
|
107
107
|
class activeTableImple : public activeObject<map_orm>
|
108
108
|
{
|
109
109
|
|
110
110
|
typedef recordsetImple Container;
|
111
|
-
typedef
|
111
|
+
typedef writableRecord* record;
|
112
112
|
typedef activeObject<map_orm> baseClass_type;
|
113
113
|
typedef std::vector<std::vector<int> > joinmap_type;
|
114
114
|
record m_record;
|
115
|
+
int m_tmpIndex;
|
115
116
|
|
116
117
|
// return can memcpy
|
117
118
|
uchar_td convertFieldType(uchar_td v)
|
@@ -130,23 +131,24 @@ class activeTableImple : public activeObject<map_orm>
|
|
130
131
|
}
|
131
132
|
|
132
133
|
template <class Container>
|
133
|
-
inline
|
134
|
-
|
135
|
-
const fieldNames& fns,
|
134
|
+
inline bool makeJoinFieldInfo(Container& mdls, const fielddefs* fds,
|
135
|
+
const _TCHAR* fns[], int fnsCount,
|
136
136
|
std::vector<typename Container::key_type>& fieldIndexes,
|
137
137
|
std::vector<joinInfo>& joinFields)
|
138
138
|
{
|
139
|
-
joinFields.resize(
|
140
|
-
fieldIndexes.resize(
|
139
|
+
joinFields.resize(fnsCount);
|
140
|
+
fieldIndexes.resize(fnsCount);
|
141
141
|
const tabledef* td = table()->tableDef();
|
142
142
|
const keydef* kd = &td->keyDefs[table()->keyNum()];
|
143
|
-
if (kd->segmentCount <
|
143
|
+
if (kd->segmentCount < fnsCount)
|
144
144
|
THROW_BZS_ERROR_WITH_MSG(_T("Join key fields are too many.\n ")
|
145
145
|
_T("Check index number and field count."));
|
146
146
|
|
147
|
-
|
147
|
+
bool hasMany = ((kd->segmentCount > fnsCount) || kd->segments[0].flags.bit0);/* duplicate key*/
|
148
|
+
|
149
|
+
for (int i = 0; i < fnsCount; ++i)
|
148
150
|
{
|
149
|
-
std::_tstring s = fns
|
151
|
+
std::_tstring s = fns[i];
|
150
152
|
if (s[0] == '[')
|
151
153
|
{
|
152
154
|
fieldIndexes[i] = -1;
|
@@ -174,29 +176,7 @@ class activeTableImple : public activeObject<map_orm>
|
|
174
176
|
}
|
175
177
|
}
|
176
178
|
}
|
177
|
-
|
178
|
-
|
179
|
-
template <class Container>
|
180
|
-
inline void
|
181
|
-
addSeekValues(row& mdl, queryBase& q,
|
182
|
-
std::vector<typename Container::key_type>& fieldIndexes,
|
183
|
-
std::vector<joinInfo>& joinFields)
|
184
|
-
{
|
185
|
-
for (int i = 0; i < (int)fieldIndexes.size(); ++i)
|
186
|
-
{
|
187
|
-
if (fieldIndexes[i] == -1)
|
188
|
-
q.addSeekKeyValuePtr(joinFields[i].fixedValue.c_str(),
|
189
|
-
joinFields[i].len, KEYVALUE_STR);
|
190
|
-
else if (joinFields[i].type == JOIN_KEYVALUE_TYPE_PTR)
|
191
|
-
q.addSeekKeyValuePtr(mdl[fieldIndexes[i]].ptr(),
|
192
|
-
joinFields[i].len, KEYVALUE_PTR);
|
193
|
-
else
|
194
|
-
{
|
195
|
-
const _TCHAR* p = mdl[fieldIndexes[i]].c_str();
|
196
|
-
q.addSeekKeyValuePtr(p, (ushort_td)_tcslen(p),
|
197
|
-
KEYVALUE_STR_NEED_COPY);
|
198
|
-
}
|
199
|
-
}
|
179
|
+
return hasMany;
|
200
180
|
}
|
201
181
|
|
202
182
|
template <class Container>
|
@@ -220,64 +200,106 @@ class activeTableImple : public activeObject<map_orm>
|
|
220
200
|
}
|
221
201
|
}
|
222
202
|
|
203
|
+
|
223
204
|
template <class Container>
|
224
|
-
void
|
205
|
+
inline void addSeekValues(row& mdl, pq_handle& q,
|
206
|
+
std::vector<typename Container::key_type>& fieldIndexes,
|
207
|
+
std::vector<joinInfo>& joinFields)
|
208
|
+
{
|
209
|
+
const uchar_td* ptr[8];
|
210
|
+
int len[8];
|
211
|
+
for (int i = 0; i < (int)fieldIndexes.size(); ++i)
|
212
|
+
{
|
213
|
+
if (fieldIndexes[i] == -1)
|
214
|
+
{
|
215
|
+
ptr[i] = (const uchar_td*)joinFields[i].fixedValue.c_str();
|
216
|
+
len[i] = joinFields[i].len;
|
217
|
+
}
|
218
|
+
else if (joinFields[i].type == JOIN_KEYVALUE_TYPE_PTR)
|
219
|
+
{
|
220
|
+
ptr[i] = (const uchar_td*)mdl[fieldIndexes[i]].ptr();
|
221
|
+
len[i] = joinFields[i].len;
|
222
|
+
}
|
223
|
+
else
|
224
|
+
{
|
225
|
+
const _TCHAR* p = mdl[fieldIndexes[i]].c_str();
|
226
|
+
ptr[i] = (const uchar_td*)p;
|
227
|
+
len[i] = (int)_tcslen(p);
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
if (!q->supplySeekValue(ptr, len, (int)fieldIndexes.size(), m_tmpIndex))
|
232
|
+
THROW_BZS_ERROR_WITH_MSG(_T("Join key value(s) are invalid at supply values to prepared statement or query.\n ")
|
233
|
+
_T("Check prepared statement or query."));
|
234
|
+
}
|
235
|
+
|
236
|
+
int makeJoinKeys(const _TCHAR* fns[MAX_JOIN_KEY_SIZE], int &fnsCount, const _TCHAR* name1,
|
225
237
|
const _TCHAR* name2 = NULL, const _TCHAR* name3 = NULL,
|
226
238
|
const _TCHAR* name4 = NULL, const _TCHAR* name5 = NULL,
|
227
239
|
const _TCHAR* name6 = NULL, const _TCHAR* name7 = NULL,
|
228
240
|
const _TCHAR* name8 = NULL)
|
229
241
|
{
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
242
|
+
int count = 0;
|
243
|
+
fns[0] = name1; fns[1] = name2; fns[2] = name3; fns[3] = name4;
|
244
|
+
fns[4] = name5; fns[5] = name6; fns[6] = name7; fns[7] = name8;
|
245
|
+
|
246
|
+
for (count = 0; count < MAX_JOIN_KEY_SIZE; ++count)
|
247
|
+
if ((fns[count] == NULL) || (fns[count][0] == 0x00))
|
248
|
+
break;
|
249
|
+
return count;
|
250
|
+
}
|
234
251
|
|
252
|
+
inline void reserveSeekSize(pq_handle& q, size_t size, int keySize)
|
253
|
+
{
|
254
|
+
q->beginSupplySeekValues(size, keySize);
|
255
|
+
m_tmpIndex = 0;
|
256
|
+
}
|
257
|
+
|
258
|
+
template <class Container>
|
259
|
+
void doJoin(bool innner, Container& mdls, pq_handle& stmt, const _TCHAR* fns[8], int fnsCount)
|
260
|
+
{
|
261
|
+
stmt->clearSeeks();
|
235
262
|
mraResetter mras(m_tb);
|
236
263
|
typename Container::iterator it = mdls.begin(), ite = mdls.end();
|
237
264
|
|
238
|
-
bool optimize = !(q.getOptimize() & queryBase::joinHasOneOrHasMany);
|
239
265
|
joinmap_type joinRowMap;
|
240
266
|
|
241
|
-
fieldNames fns;
|
242
|
-
fns.keyField(name1, name2, name3, name4, name5, name6, name7, name8);
|
243
|
-
|
244
267
|
std::vector<typename Container::key_type> fieldIndexes;
|
245
268
|
std::vector<joinInfo> joinFields;
|
246
269
|
|
247
270
|
const fielddefs* fds = mdls.fieldDefs();
|
248
|
-
makeJoinFieldInfo<Container>(mdls, fds, fns, fieldIndexes, joinFields);
|
271
|
+
bool hasMany = makeJoinFieldInfo<Container>(mdls, fds, fns, fnsCount, fieldIndexes, joinFields);
|
272
|
+
if (!hasMany)
|
273
|
+
hasMany = (stmt->cachedOptimaize() & queryBase::joinHasOneOrHasMany);
|
249
274
|
|
250
275
|
// optimizing join
|
251
276
|
// if base recordsetImple is made by unique key and join by uniqe field,
|
252
277
|
// that can not opitimize.
|
253
278
|
//
|
254
|
-
|
255
|
-
if (optimize)
|
279
|
+
if (!hasMany)
|
256
280
|
{
|
257
281
|
makeJoinMap(mdls, joinRowMap, fieldIndexes);
|
258
|
-
|
259
|
-
fieldIndexes.size());
|
282
|
+
reserveSeekSize(stmt, joinRowMap.size() * fieldIndexes.size(), fnsCount);
|
260
283
|
std::vector<std::vector<int> >::iterator it1 = joinRowMap.begin(),
|
261
284
|
ite1 = joinRowMap.end();
|
262
285
|
while (it1 != ite1)
|
263
286
|
{
|
264
287
|
row& mdl = *(mdls.getRow((*it1)[0]));
|
265
|
-
addSeekValues<Container>(mdl,
|
288
|
+
addSeekValues<Container>(mdl, stmt, fieldIndexes, joinFields);
|
266
289
|
++it1;
|
267
290
|
}
|
268
291
|
}
|
269
292
|
else
|
270
293
|
{
|
271
|
-
|
294
|
+
reserveSeekSize(stmt, mdls.size() * fieldIndexes.size(), fnsCount);
|
272
295
|
while (it != ite)
|
273
296
|
{
|
274
297
|
row& mdl = *(*it);
|
275
|
-
addSeekValues<Container>(mdl,
|
298
|
+
addSeekValues<Container>(mdl, stmt, fieldIndexes, joinFields);
|
276
299
|
++it;
|
277
300
|
}
|
278
301
|
}
|
279
302
|
|
280
|
-
m_tb->setQuery(&q);
|
281
303
|
if (m_tb->stat() != 0)
|
282
304
|
nstable::throwError(_T("activeObject Join Query"), &(*m_tb));
|
283
305
|
|
@@ -289,7 +311,7 @@ class activeTableImple : public activeObject<map_orm>
|
|
289
311
|
if (m_tb->mra())
|
290
312
|
{
|
291
313
|
m_tb->mra()->setJoinType(innner ? mra_innerjoin : mra_outerjoin);
|
292
|
-
if (
|
314
|
+
if (!hasMany)
|
293
315
|
m_tb->mra()->setJoinRowMap(&joinRowMap);
|
294
316
|
}
|
295
317
|
m_tb->find();
|
@@ -320,21 +342,36 @@ class activeTableImple : public activeObject<map_orm>
|
|
320
342
|
}
|
321
343
|
}
|
322
344
|
|
345
|
+
inline void checkPreparedQuery(pq_handle& q)
|
346
|
+
{
|
347
|
+
if (!q)
|
348
|
+
THROW_BZS_ERROR_WITH_MSG(_T("Invalid query or prepqredQuery.\n "));
|
349
|
+
}
|
350
|
+
|
323
351
|
public:
|
324
352
|
explicit activeTableImple(idatabaseManager* mgr, const _TCHAR* tableName)
|
325
|
-
: baseClass_type(mgr, tableName){};
|
353
|
+
: baseClass_type(mgr, tableName), m_record(NULL){};
|
326
354
|
|
327
355
|
explicit activeTableImple(database_ptr& db, const _TCHAR* tableName)
|
328
|
-
: baseClass_type(db, tableName){};
|
356
|
+
: baseClass_type(db, tableName), m_record(NULL){};
|
329
357
|
|
330
358
|
explicit activeTableImple(database* db, const _TCHAR* tableName)
|
331
|
-
: baseClass_type(db, tableName){};
|
359
|
+
: baseClass_type(db, tableName), m_record(NULL){};
|
360
|
+
|
361
|
+
~activeTableImple()
|
362
|
+
{
|
363
|
+
if (m_record)
|
364
|
+
m_record->release();
|
365
|
+
}
|
332
366
|
|
333
367
|
inline writableRecord& getWritableRecord()
|
334
368
|
{
|
335
|
-
m_record
|
336
|
-
|
337
|
-
|
369
|
+
if (m_record == NULL)
|
370
|
+
{
|
371
|
+
m_record = writableRecord::create(m_tb.get(), &m_alias);
|
372
|
+
m_record->addref();
|
373
|
+
}
|
374
|
+
return *m_record;
|
338
375
|
}
|
339
376
|
|
340
377
|
inline void join(Container& mdls, queryBase& q, const _TCHAR* name1,
|
@@ -343,8 +380,14 @@ public:
|
|
343
380
|
const _TCHAR* name6 = NULL, const _TCHAR* name7 = NULL,
|
344
381
|
const _TCHAR* name8 = NULL)
|
345
382
|
{
|
346
|
-
|
347
|
-
|
383
|
+
const _TCHAR* fns[MAX_JOIN_KEY_SIZE];
|
384
|
+
m_alias.reverseAliasNamesQuery(q);
|
385
|
+
int fnsCount = makeJoinKeys(fns, fnsCount, name1, name2, name3, name4,
|
386
|
+
name5, name6, name7, name8);
|
387
|
+
q.joinKeySize(fnsCount);
|
388
|
+
pq_handle pq = setQuery(m_tb, q);
|
389
|
+
checkPreparedQuery(pq);
|
390
|
+
doJoin(true, mdls, pq, fns, fnsCount);
|
348
391
|
}
|
349
392
|
|
350
393
|
inline void
|
@@ -354,8 +397,44 @@ public:
|
|
354
397
|
const _TCHAR* name6 = NULL, const _TCHAR* name7 = NULL,
|
355
398
|
const _TCHAR* name8 = NULL)
|
356
399
|
{
|
357
|
-
|
358
|
-
|
400
|
+
const _TCHAR* fns[MAX_JOIN_KEY_SIZE];
|
401
|
+
m_alias.reverseAliasNamesQuery(q);
|
402
|
+
int fnsCount = makeJoinKeys(fns, fnsCount, name1, name2, name3, name4,
|
403
|
+
name5, name6, name7, name8);
|
404
|
+
q.joinKeySize(fnsCount);
|
405
|
+
pq_handle pq = setQuery(m_tb, q);
|
406
|
+
checkPreparedQuery(pq);
|
407
|
+
doJoin(false, mdls, pq, fns, fnsCount);
|
408
|
+
|
409
|
+
}
|
410
|
+
|
411
|
+
inline void join(Container& mdls, pq_handle& q, const _TCHAR* name1,
|
412
|
+
const _TCHAR* name2 = NULL, const _TCHAR* name3 = NULL,
|
413
|
+
const _TCHAR* name4 = NULL, const _TCHAR* name5 = NULL,
|
414
|
+
const _TCHAR* name6 = NULL, const _TCHAR* name7 = NULL,
|
415
|
+
const _TCHAR* name8 = NULL)
|
416
|
+
{
|
417
|
+
const _TCHAR* fns[MAX_JOIN_KEY_SIZE];
|
418
|
+
int fnsCount = makeJoinKeys(fns, fnsCount, name1, name2, name3, name4,
|
419
|
+
name5, name6, name7, name8);
|
420
|
+
pq_handle pq = setQuery(m_tb, q);
|
421
|
+
checkPreparedQuery(pq);
|
422
|
+
doJoin(true, mdls, pq, fns, fnsCount);
|
423
|
+
}
|
424
|
+
|
425
|
+
inline void
|
426
|
+
outerJoin(Container& mdls, pq_handle& q, const _TCHAR* name1,
|
427
|
+
const _TCHAR* name2 = NULL, const _TCHAR* name3 = NULL,
|
428
|
+
const _TCHAR* name4 = NULL, const _TCHAR* name5 = NULL,
|
429
|
+
const _TCHAR* name6 = NULL, const _TCHAR* name7 = NULL,
|
430
|
+
const _TCHAR* name8 = NULL)
|
431
|
+
{
|
432
|
+
const _TCHAR* fns[MAX_JOIN_KEY_SIZE];
|
433
|
+
int fnsCount = makeJoinKeys(fns, fnsCount, name1, name2, name3, name4,
|
434
|
+
name5, name6, name7, name8);
|
435
|
+
pq_handle pq = setQuery(m_tb, q);
|
436
|
+
checkPreparedQuery(pq);
|
437
|
+
doJoin(false, mdls, pq, fns, fnsCount);
|
359
438
|
}
|
360
439
|
|
361
440
|
void releaseTable() { m_tb.reset(); }
|
@@ -43,44 +43,47 @@ __THREAD client* __THREAD_BCB g_client = NULL;
|
|
43
43
|
|
44
44
|
bool checkVersion(trdVersiton& ver)
|
45
45
|
{
|
46
|
-
if ((ver.srvMajor <
|
46
|
+
if ((ver.srvMajor < 2) || ((ver.srvMajor == 2) && (ver.srvMinor < 1)))
|
47
47
|
return false;
|
48
48
|
return true;
|
49
49
|
}
|
50
50
|
|
51
|
-
|
51
|
+
int client::getServerCharsetIndex()
|
52
52
|
{
|
53
|
-
|
53
|
+
bzs::netsvc::client::connection* c = con();
|
54
|
+
if (!c)
|
55
|
+
return -1;
|
56
|
+
int v = c->charsetServer();
|
57
|
+
if (v != -1)
|
58
|
+
return v;
|
59
|
+
|
60
|
+
request req = m_req;
|
61
|
+
req.paramMask = P_MASK_POSBLK | P_MASK_DATA | P_MASK_DATALEN;
|
62
|
+
trdVersiton ver;
|
63
|
+
memset(&ver, 0, sizeof(trdVersiton));
|
64
|
+
ver.cherserServer[0] = 0x00;
|
65
|
+
ver.clMajor = (ushort_td)atoi(C_INTERFACE_VER_MAJOR);
|
66
|
+
ver.clMinor = (ushort_td)atoi(C_INTERFACE_VER_MINOR);
|
67
|
+
ver.clRelease = (ushort_td)atoi(C_INTERFACE_VER_RELEASE);
|
68
|
+
|
69
|
+
uint_td len = sizeof(trdVersiton);
|
70
|
+
req.op = TD_GETSERVER_CHARSET;
|
71
|
+
req.data = &ver;
|
72
|
+
req.datalen = &len;
|
73
|
+
|
74
|
+
mutex::scoped_lock lck(m_mutex);
|
75
|
+
char* p = con()->sendBuffer(m_req.sendLenEstimate());
|
76
|
+
unsigned int size = req.serialize(p);
|
77
|
+
p = con()->asyncWriteRead(size);
|
78
|
+
req.parse(p, false);
|
79
|
+
if (req.result == 0)
|
54
80
|
{
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
ver.cherserServer[0] = 0x00;
|
60
|
-
ver.clMajor = (ushort_td)atoi(C_INTERFACE_VER_MAJOR);
|
61
|
-
ver.clMinor = (ushort_td)atoi(C_INTERFACE_VER_MINOR);
|
62
|
-
ver.clRelease = (ushort_td)atoi(C_INTERFACE_VER_RELEASE);
|
63
|
-
|
64
|
-
uint_td len = sizeof(trdVersiton);
|
65
|
-
req.op = TD_GETSERVER_CHARSET;
|
66
|
-
req.data = &ver;
|
67
|
-
req.datalen = &len;
|
68
|
-
|
69
|
-
mutex::scoped_lock lck(m_mutex);
|
70
|
-
char* p = con()->sendBuffer(m_req.sendLenEstimate());
|
71
|
-
unsigned int size = req.serialize(p);
|
72
|
-
p = con()->asyncWriteRead(size);
|
73
|
-
req.parse(p, 0, 0);
|
74
|
-
if (req.result == 0)
|
75
|
-
{
|
76
|
-
if (!checkVersion(ver))
|
77
|
-
return false;
|
78
|
-
m_charsetIndexServer = mysql::charsetIndex(ver.cherserServer);
|
79
|
-
return true;
|
80
|
-
}
|
81
|
-
return false;
|
81
|
+
if (!checkVersion(ver))
|
82
|
+
return false;
|
83
|
+
c->setCharsetServer(mysql::charsetIndex(ver.cherserServer));
|
84
|
+
return c->charsetServer();
|
82
85
|
}
|
83
|
-
return
|
86
|
+
return -1;
|
84
87
|
}
|
85
88
|
|
86
89
|
void client::addSecondCharsetData(unsigned int destCodePage, std::string& src)
|
@@ -97,12 +100,13 @@ void client::addSecondCharsetData(unsigned int destCodePage, std::string& src)
|
|
97
100
|
|
98
101
|
bool client::buildDualChasetKeybuf()
|
99
102
|
{
|
100
|
-
|
103
|
+
int charsetIndexServer = getServerCharsetIndex();
|
104
|
+
if (charsetIndexServer == -1)
|
101
105
|
return false;
|
102
|
-
|
106
|
+
|
103
107
|
m_serverCharData = (char*)m_req.keybuf;
|
104
|
-
if (CHARSET_UTF8 !=
|
105
|
-
addSecondCharsetData(mysql::codePage(
|
108
|
+
if (CHARSET_UTF8 != charsetIndexServer)
|
109
|
+
addSecondCharsetData(mysql::codePage(charsetIndexServer),
|
106
110
|
m_serverCharData);
|
107
111
|
else
|
108
112
|
m_serverCharData += std::string("\t") + (char*)m_req.keybuf;
|
@@ -52,24 +52,24 @@ namespace client
|
|
52
52
|
class client;
|
53
53
|
void setClientThread(client* v);
|
54
54
|
|
55
|
+
/* client class
|
56
|
+
This instance is created for each thread.
|
57
|
+
*/
|
55
58
|
class client
|
56
59
|
{
|
57
|
-
|
58
60
|
mutex m_mutex;
|
59
61
|
request m_req;
|
60
62
|
posblk m_tmpPbk;
|
61
63
|
ushort_td m_op;
|
62
64
|
ushort_td m_preResult;
|
63
|
-
int m_charsetIndexServer;
|
64
|
-
|
65
65
|
std::string m_sql;
|
66
66
|
std::string m_serverCharData;
|
67
67
|
std::string m_serverCharData2;
|
68
|
-
|
68
|
+
blobBuffer m_blobBuffer;
|
69
69
|
uint_td m_tmplen;
|
70
70
|
bool m_logout;
|
71
|
-
blobBuffer m_blobBuffer;
|
72
71
|
bool m_disconnected;
|
72
|
+
bool m_connecting;
|
73
73
|
|
74
74
|
std::vector<char> m_sendbuf;
|
75
75
|
|
@@ -78,16 +78,17 @@ class client
|
|
78
78
|
inline void setCon(bzs::netsvc::client::connection* con)
|
79
79
|
{
|
80
80
|
m_req.cid->con = con;
|
81
|
-
}
|
81
|
+
}
|
82
82
|
|
83
83
|
inline void disconnect()
|
84
84
|
{
|
85
85
|
if (!con())
|
86
86
|
m_req.result = 1;
|
87
87
|
else
|
88
|
+
{
|
88
89
|
m_disconnected = m_cons->disconnect(con());
|
89
|
-
if (m_req.result == 0)
|
90
90
|
setCon(NULL);
|
91
|
+
}
|
91
92
|
}
|
92
93
|
|
93
94
|
std::string getHostName(const char* uri)
|
@@ -123,15 +124,26 @@ class client
|
|
123
124
|
std::string& src);
|
124
125
|
|
125
126
|
public:
|
126
|
-
client() :
|
127
|
+
client() : m_disconnected(true), m_connecting(false) {}
|
127
128
|
|
128
129
|
void cleanup()
|
129
130
|
{
|
131
|
+
m_connecting = false;
|
132
|
+
/* When in win32, delete this object auto maticaly by dllmain function
|
133
|
+
at reason = DLL_THREAD_DETACH.
|
134
|
+
But in LINUX does not have that mechanism.
|
135
|
+
Each dissconnect delete this object.
|
136
|
+
|
137
|
+
*/
|
138
|
+
|
139
|
+
#ifndef _WIN32
|
140
|
+
// delete this. Do not change member variables after this line.
|
130
141
|
if (m_disconnected)
|
131
142
|
setClientThread(NULL);
|
143
|
+
#endif
|
132
144
|
}
|
133
145
|
|
134
|
-
request& req() { return m_req; }
|
146
|
+
inline request& req() { return m_req; }
|
135
147
|
|
136
148
|
inline void setParam(ushort_td op, posblk* pbk, void_td* data,
|
137
149
|
uint_td* datalen, void_td* keybuf, keylen_td keylen,
|
@@ -170,12 +182,16 @@ public:
|
|
170
182
|
{
|
171
183
|
if (!m_req.cid->con)
|
172
184
|
{
|
185
|
+
|
173
186
|
std::string host = getHostName((const char*)m_req.keybuf);
|
174
187
|
if (host == "")
|
175
188
|
m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
|
176
189
|
bzs::netsvc::client::connection* c = m_cons->connect(host);
|
177
190
|
if (c)
|
191
|
+
{
|
178
192
|
setCon(c);
|
193
|
+
m_connecting = true;
|
194
|
+
}
|
179
195
|
else
|
180
196
|
m_preResult = ERROR_TD_HOSTNAME_NOT_FOUND;
|
181
197
|
}
|
@@ -192,15 +208,16 @@ public:
|
|
192
208
|
{
|
193
209
|
m_req.paramMask &= ~P_MASK_POSBLK;
|
194
210
|
std::string name = getTableName((const char*)m_req.keybuf);
|
211
|
+
int charsetIndexServer = getServerCharsetIndex();
|
195
212
|
if ((m_req.keyNum == 1) || (m_req.keyNum == 2)) // make by tabledef
|
196
213
|
{
|
197
214
|
m_sql = sqlCreateTable(name.c_str(), (tabledef*)m_req.data,
|
198
|
-
|
215
|
+
charsetIndexServer);
|
199
216
|
m_req.keyNum -= 2; // 1= exists check 2 = no exists check
|
200
217
|
}
|
201
218
|
else
|
202
219
|
m_sql = sqlCreateTable(name.c_str(), (fileSpec*)m_req.data,
|
203
|
-
|
220
|
+
charsetIndexServer);
|
204
221
|
m_req.data = (ushort_td*)m_sql.c_str();
|
205
222
|
m_tmplen = (uint_td)(m_sql.size() + 1);
|
206
223
|
m_req.datalen = &m_tmplen;
|
@@ -208,9 +225,9 @@ public:
|
|
208
225
|
else if ((m_req.keyNum == CR_SUBOP_SWAPNAME) ||
|
209
226
|
(m_req.keyNum == CR_SUBOP_RENAME))
|
210
227
|
{
|
211
|
-
|
228
|
+
int charsetIndexServer = getServerCharsetIndex();
|
212
229
|
m_sql = (char*)m_req.data;
|
213
|
-
addSecondCharsetData(mysql::codePage(
|
230
|
+
addSecondCharsetData(mysql::codePage(charsetIndexServer), m_sql);
|
214
231
|
m_req.data = (ushort_td*)m_sql.c_str();
|
215
232
|
m_tmplen = (uint_td)(m_sql.size() + 1);
|
216
233
|
m_req.datalen = &m_tmplen;
|
@@ -234,7 +251,7 @@ public:
|
|
234
251
|
if (c)
|
235
252
|
{
|
236
253
|
setCon(c); // if error throw exception
|
237
|
-
if (
|
254
|
+
if (getServerCharsetIndex() == -1)
|
238
255
|
m_preResult = SERVER_CLIENT_NOT_COMPATIBLE;
|
239
256
|
else
|
240
257
|
buildDualChasetKeybuf();
|
@@ -257,27 +274,38 @@ public:
|
|
257
274
|
{
|
258
275
|
if (result() == 0)
|
259
276
|
{
|
260
|
-
|
277
|
+
bzs::netsvc::client::connection* c = con();
|
278
|
+
if (!c)
|
261
279
|
m_preResult = ERROR_TD_NOT_CONNECTED;
|
262
280
|
else
|
263
281
|
{
|
264
|
-
char* p =
|
282
|
+
char* p = c->sendBuffer(m_req.sendLenEstimate());
|
265
283
|
unsigned int size = m_req.serialize(p);
|
266
284
|
short stat = 0;
|
267
285
|
if ((m_req.paramMask & P_MASK_BLOBBODY) && m_blobBuffer.blobs())
|
268
286
|
size = m_req.serializeBlobBody(
|
269
|
-
&m_blobBuffer, p, size,
|
270
|
-
|
287
|
+
&m_blobBuffer, p, size, c->sendBufferSize(),
|
288
|
+
c->optionalBuffers(), stat);
|
271
289
|
if (stat == 0)
|
272
290
|
{
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
291
|
+
bool ex = (m_req.paramMask & P_MASK_EX_SENDLEN) != 0;
|
292
|
+
if (c->queryFunction(CONNECTION_FUNCTION_DIRECT_READ) && ex)
|
293
|
+
{
|
294
|
+
c->setDirectReadHandler(&m_req);
|
295
|
+
p = c->asyncWriteRead(size);
|
296
|
+
c->setDirectReadHandler(NULL);
|
297
|
+
}else
|
298
|
+
{
|
299
|
+
if (m_req.paramMask & P_MASK_DATALEN)
|
300
|
+
c->setReadBufferSizeIf(*m_req.datalen);
|
301
|
+
p = c->asyncWriteRead(size);
|
302
|
+
m_req.parse(p, ex);
|
303
|
+
}
|
304
|
+
|
277
305
|
}
|
278
306
|
else
|
279
307
|
m_req.result = stat;
|
280
|
-
if (m_logout)
|
308
|
+
if (m_logout || (m_connecting && m_req.result))
|
281
309
|
disconnect();
|
282
310
|
m_preResult = m_req.result;
|
283
311
|
}
|
@@ -289,7 +317,6 @@ public:
|
|
289
317
|
{
|
290
318
|
*data = m_req.blobHeader;
|
291
319
|
return *data ? 0 : 1;
|
292
|
-
;
|
293
320
|
}
|
294
321
|
|
295
322
|
inline ushort_td addBlob(const blob* data, bool endRow)
|
@@ -306,7 +333,7 @@ public:
|
|
306
333
|
m_blobBuffer.addBlob(*data);
|
307
334
|
return 0;
|
308
335
|
}
|
309
|
-
|
336
|
+
int getServerCharsetIndex();
|
310
337
|
|
311
338
|
bool buildDualChasetKeybuf();
|
312
339
|
};
|