transactd 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
  };