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
@@ -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 boost::shared_ptr<writableRecord> record;
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 void
134
- makeJoinFieldInfo(Container& mdls, const fielddefs* fds,
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(fns.count());
140
- fieldIndexes.resize(fns.count());
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 < fns.count())
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
- for (int i = 0; i < fns.count(); ++i)
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.getValue(i);
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 doJoin(bool innner, Container& mdls, queryBase& q, const _TCHAR* name1,
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
- if (mdls.size() == 0)
231
- return;
232
- m_alias.reverseAliasNamesQuery(q);
233
- q.clearSeekKeyValues();
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
- q.joinKeySize(fns.count());
255
- if (optimize)
279
+ if (!hasMany)
256
280
  {
257
281
  makeJoinMap(mdls, joinRowMap, fieldIndexes);
258
- q.reserveSeekKeyValuePtrSize(joinRowMap.size() *
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, q, fieldIndexes, joinFields);
288
+ addSeekValues<Container>(mdl, stmt, fieldIndexes, joinFields);
266
289
  ++it1;
267
290
  }
268
291
  }
269
292
  else
270
293
  {
271
- q.reserveSeekKeyValuePtrSize(mdls.size() * fieldIndexes.size());
294
+ reserveSeekSize(stmt, mdls.size() * fieldIndexes.size(), fnsCount);
272
295
  while (it != ite)
273
296
  {
274
297
  row& mdl = *(*it);
275
- addSeekValues<Container>(mdl, q, fieldIndexes, joinFields);
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 (optimize)
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.reset(writableRecord::create(m_tb.get(), &m_alias),
336
- &writableRecord::release);
337
- return *m_record.get();
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
- doJoin(true, mdls, q, name1, name2, name3, name4, name5, name6, name7,
347
- name8);
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
- doJoin(false, mdls, q, name1, name2, name3, name4, name5, name6, name7,
358
- name8);
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 < 1) || ((ver.srvMajor == 1) && (ver.srvMinor < 3)))
46
+ if ((ver.srvMajor < 2) || ((ver.srvMajor == 2) && (ver.srvMinor < 1)))
47
47
  return false;
48
48
  return true;
49
49
  }
50
50
 
51
- bool client::readServerCharsetIndex()
51
+ int client::getServerCharsetIndex()
52
52
  {
53
- if (m_charsetIndexServer == -1)
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
- request req = m_req;
56
- req.paramMask = P_MASK_POSBLK | P_MASK_DATA | P_MASK_DATALEN;
57
- trdVersiton ver;
58
- memset(&ver, 0, sizeof(trdVersiton));
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 true;
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
- if (!readServerCharsetIndex())
103
+ int charsetIndexServer = getServerCharsetIndex();
104
+ if (charsetIndexServer == -1)
101
105
  return false;
102
- // m_serverCharData = std::string((char*)m_req.keybuf, m_req.keylen);
106
+
103
107
  m_serverCharData = (char*)m_req.keybuf;
104
- if (CHARSET_UTF8 != m_charsetIndexServer)
105
- addSecondCharsetData(mysql::codePage(m_charsetIndexServer),
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() : m_charsetIndexServer(-1), m_disconnected(true) {}
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
- m_charsetIndexServer);
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
- m_charsetIndexServer);
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
- readServerCharsetIndex();
228
+ int charsetIndexServer = getServerCharsetIndex();
212
229
  m_sql = (char*)m_req.data;
213
- addSecondCharsetData(mysql::codePage(m_charsetIndexServer), m_sql);
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 (readServerCharsetIndex() == false)
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
- if (!con())
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 = con()->sendBuffer(m_req.sendLenEstimate());
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, con()->sendBufferSize(),
270
- con()->optionalBuffers(), stat);
287
+ &m_blobBuffer, p, size, c->sendBufferSize(),
288
+ c->optionalBuffers(), stat);
271
289
  if (stat == 0)
272
290
  {
273
- if (m_req.paramMask & P_MASK_DATALEN)
274
- con()->setReadBufferSizeIf(*m_req.datalen);
275
- p = con()->asyncWriteRead(size);
276
- m_req.parse(p, con()->datalen(), con()->rows());
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
- bool readServerCharsetIndex();
336
+ int getServerCharsetIndex();
310
337
 
311
338
  bool buildDualChasetKeybuf();
312
339
  };