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
@@ -65,14 +65,17 @@ namespace mysql
65
65
  #define TRN_RECORD_LOCK_SINGLE 0
66
66
  #define TRN_RECORD_LOCK_MUILTI 1
67
67
 
68
+ #define MODE_READ_ONLY -2
69
+ #define MODE_EXCLUSIVE -4
70
+ #define MODE_READ_EXCLUSIVE -6
71
+
72
+
68
73
  /** bookmark size
69
74
  * btreive API is MAX 4 byte
70
75
  */
71
76
  #define REF_SIZE_MAX 4
72
77
  class table;
73
78
 
74
- extern bool g_safe_share_mode;
75
-
76
79
  /** Control mysql table cahche
77
80
  */
78
81
  class tableCacheCounter
@@ -92,27 +95,43 @@ public:
92
95
  void release(const std::string& dbname, const std::string& tbname);
93
96
  };
94
97
 
98
+ struct rowLockMode
99
+ {
100
+ bool lock : 1;
101
+ bool read : 1;
102
+ };
103
+
95
104
  class database : private boost::noncopyable
96
105
  {
97
106
  friend class table;
98
107
  friend class smartDbReopen;
99
-
108
+ public:
109
+ typedef std::vector<boost::shared_ptr<table> > tableList;
110
+ private:
100
111
  std::string m_dbname;
101
-
102
112
  mutable THD* m_thd;
103
- short m_cid;
104
113
  int m_inTransaction;
105
114
  int m_inSnapshot;
106
115
  int m_stat;
116
+ int m_usingExclusive;
117
+ table* m_inAutoTransaction;
107
118
  short m_trnType;
108
-
109
- std::vector<boost::shared_ptr<table> > m_tables;
119
+ short m_cid;
120
+ enum_tx_isolation m_iso;
121
+ tableList m_tables;
122
+
110
123
  TABLE* doOpenTable(const std::string& name, short mode,
111
- const char* ownerName);
112
-
124
+ const char* ownerName);
113
125
  void unUseTable(table* tb);
126
+ size_t getNomalOpenTables(tableList& tables);
127
+ void prebuildIsoratinMode();
128
+ void prebuildExclusieLockMode(table* tb);
129
+ void prebuildLocktype(table* tb, enum_sql_command& cmd, rowLockMode* lck) ;
130
+ void changeIntentionLock(table* tb, thr_lock_type lock_type);
114
131
 
115
132
  public:
133
+
134
+
116
135
  database(const char* name, short cid);
117
136
  ~database();
118
137
 
@@ -136,12 +155,12 @@ public:
136
155
  return m_tables;
137
156
  }
138
157
 
139
- bool beginSnapshot();
158
+ bool beginSnapshot(enum_tx_isolation iso);
140
159
  bool endSnapshot();
141
160
  table* openTable(const std::string& name, short mode,
142
161
  const char* ownerName);
143
- table* useTable(int index, enum_sql_command cmd);
144
- bool beginTrn(short type);
162
+ table* useTable(int index, enum_sql_command cmd, rowLockMode* lck);
163
+ bool beginTrn(short type, enum_tx_isolation iso);
145
164
  bool commitTrn();
146
165
  bool abortTrn();
147
166
  bool existsTable(const std::string& name);
@@ -153,14 +172,29 @@ public:
153
172
  void reopen();
154
173
  void cleanTable();
155
174
 
175
+ inline bool canUnlockRow() const
176
+ {
177
+ /* inSnapshot or inTransaction multi record lock do not unlock */
178
+ if (m_inSnapshot || (m_inTransaction && (m_trnType == TRN_RECORD_LOCK_MUILTI)))
179
+ return false;
180
+ return true;
181
+ }
182
+
183
+ inline bool noUserTransaction() const
184
+ {
185
+ return ((m_inSnapshot + m_inTransaction) == 0);
186
+ }
187
+
156
188
  static tableCacheCounter tableRef;
157
189
  };
158
190
 
159
191
  typedef std::vector<boost::shared_ptr<database> > databases;
160
192
 
161
193
  class IReadRecordsHandler;
194
+ class IPrepare;
162
195
  class bookmarks;
163
196
 
197
+
164
198
  /*
165
199
  * Since it differs from the key number which a client specifies
166
200
  * , and an internal key number, it changes.
@@ -198,41 +232,46 @@ public:
198
232
  class table : private boost::noncopyable
199
233
  {
200
234
  friend class database;
235
+ friend struct smartForceConsistantRead;
201
236
  TABLE* m_table;
202
237
 
203
238
  std::string m_name;
204
239
 
205
- const short m_mode;
206
- int m_id;
240
+ short m_mode;
207
241
  unsigned short m_nullFields;
242
+ int m_id;
208
243
  uint m_recordLenCl;
209
244
  int m_recordFormatType;
210
245
  #ifdef USE_BTRV_VARIABLE_LEN
211
246
  uint m_lastVarLenBytes;
212
247
  #endif
213
248
  database& m_db;
214
- char m_keyNum;
215
-
216
249
  mutable boost::scoped_array<unsigned char> m_keybuf;
217
250
  mutable boost::scoped_array<unsigned char> m_nonNccKeybuf;
218
251
 
219
- bool m_nonNcc;
220
252
  int m_stat;
221
- bool m_validCursor;
222
- bool m_cursor;
223
- bool m_locked;
224
- bool m_changed;
225
- bool m_nounlock;
226
- bool m_bulkInserting;
227
253
  int m_percentResult;
228
-
229
254
  boost::shared_ptr<bookmarks> m_bms;
230
-
231
255
  String m_str;
232
256
  keynumConvert m_keyconv;
233
257
  IblobBuffer* m_blobBuffer;
234
-
235
258
  std::vector<Field*> m_nonKeySegNullFields;
259
+ char m_keyNum;
260
+ struct
261
+ {
262
+ bool m_nonNcc : 1;
263
+ bool m_validCursor : 1;
264
+ bool m_cursor : 1;
265
+ bool m_locked : 1;
266
+ bool m_changed : 1;
267
+ bool m_nounlock : 1;
268
+ bool m_bulkInserting : 1;
269
+ bool m_delayAutoCommit : 1;
270
+ };
271
+ struct
272
+ {
273
+ bool m_forceConsistentRead : 1;
274
+ };
236
275
 
237
276
  table(TABLE* table, database& db, const std::string& name, short mode,
238
277
  int id);
@@ -261,14 +300,18 @@ class table : private boost::noncopyable
261
300
  }
262
301
  void setKeyValues(const uchar* ptr, int size);
263
302
  void setBlobFieldPointer(const bzs::db::blobHeader* hd);
264
- inline void unlockRow();
265
-
266
- inline void initHandler()
303
+
304
+ inline bool setCursorStaus()
267
305
  {
268
- if ((m_db.m_inSnapshot == 0) &&
269
- (m_table->reginfo.lock_type != TL_WRITE))
270
- m_table->file->init_table_handle_for_HANDLER();
306
+ m_validCursor = (m_stat == 0);
307
+ m_cursor = (m_stat == 0) ? true :
308
+ ((m_stat == HA_ERR_LOCK_WAIT_TIMEOUT) ||
309
+ (m_stat == HA_ERR_LOCK_DEADLOCK)) ? m_cursor : false;
310
+ return m_validCursor;
271
311
  }
312
+
313
+ inline void unlockRow(bool noConsistent);
314
+ inline void tryConsistentRead(bool noConsistent);
272
315
 
273
316
  #ifdef USE_HANDLERSOCKET
274
317
  std::vector<int> m_useFields;
@@ -293,6 +336,7 @@ public:
293
336
 
294
337
  public:
295
338
  static bool noKeybufResult;
339
+ std::vector<IPrepare*> preparedStatements;
296
340
 
297
341
  ~table();
298
342
 
@@ -301,13 +345,23 @@ public:
301
345
  m_blobBuffer = blobBuffer;
302
346
  }
303
347
 
304
- inline IblobBuffer* blobBuffer(IblobBuffer* blobBuffer)
348
+ inline IblobBuffer* blobBuffer() const
305
349
  {
306
350
  return m_blobBuffer;
307
351
  }
308
352
 
309
353
  inline short mode() const { return m_mode; }
310
354
 
355
+ inline bool isReadOnly() const
356
+ {
357
+ return (m_mode == MODE_READ_ONLY)
358
+ ||(m_mode == MODE_READ_EXCLUSIVE);
359
+ }
360
+
361
+ inline bool isExclusveMode() const { return m_mode <= MODE_EXCLUSIVE;}
362
+
363
+ inline bool isNomalMode() const { return m_mode > MODE_EXCLUSIVE;}
364
+
311
365
  inline bool islocked() { return m_locked; }
312
366
 
313
367
  inline void setLocked(bool value) { m_locked = value; }
@@ -316,7 +370,17 @@ public:
316
370
 
317
371
  int id() { return m_id; };
318
372
 
319
- inline void unUse() { m_db.unUseTable(this); }
373
+ /* The singleRowLock is no effects with Transaction or Snapshot. */
374
+ inline void unUse()
375
+ {
376
+ if (m_delayAutoCommit)
377
+ {
378
+ m_delayAutoCommit = false;
379
+ m_db.m_inAutoTransaction = this;
380
+ }
381
+ else
382
+ m_db.unUseTable(this);
383
+ }
320
384
 
321
385
  inline const std::string& name() const { return m_name; }
322
386
 
@@ -326,21 +390,21 @@ public:
326
390
 
327
391
  #ifdef USE_BTRV_VARIABLE_LEN
328
392
 
329
- inline uint lastVarFiledNum() const
393
+ inline uint lastVarFieldNum() const
330
394
  {
331
395
  return m_table->s->fields - 1 - nisFields();
332
396
  }
333
397
 
334
398
  inline const Field* lastVarFiled() const
335
399
  {
336
- return m_table->s->field[lastVarFiledNum()];
400
+ return m_table->s->field[lastVarFieldNum()];
337
401
  }
338
402
 
339
403
  unsigned short lastVarLenBytes() const { return m_lastVarLenBytes; }
340
404
 
341
405
  inline unsigned short lastVarFieldDataLen() const
342
406
  {
343
- return fieldDataLen(lastVarFiledNum());
407
+ return fieldDataLen(lastVarFieldNum());
344
408
  }
345
409
 
346
410
  unsigned short lastVarFieldPos() const;
@@ -455,7 +519,7 @@ public:
455
519
  const bzs::db::blobHeader* hd);
456
520
  uint recordPackCopy(char* buf, uint maxsize = 0);
457
521
 
458
- ushort fieldPackCopy(unsigned char* dest, short filedNum);
522
+ ushort fieldPackCopy(unsigned char* dest, short fieldNum);
459
523
 
460
524
  inline uint fieldSizeByte(int fieldNum)
461
525
  {
@@ -580,6 +644,11 @@ public:
580
644
  m_blobBuffer->setFieldCount(num);
581
645
  }
582
646
 
647
+ inline uint getBlobFieldCount()
648
+ {
649
+ return m_blobBuffer->fieldCount();
650
+ }
651
+
583
652
  inline void indexInit()
584
653
  {
585
654
  int ret = m_table->file->ha_index_or_rnd_end();
@@ -590,6 +659,48 @@ public:
590
659
  ret = m_table->file->ha_rnd_init(true);
591
660
  assert(ret == 0);
592
661
  }
662
+
663
+ inline void setRowLock(rowLockMode* lck)
664
+ {
665
+ if (lck->lock && m_db.noUserTransaction() && isNomalMode())
666
+ m_delayAutoCommit = true;
667
+ else
668
+ m_delayAutoCommit = false;
669
+ }
670
+
671
+ inline void setRowLockError()
672
+ {
673
+ m_delayAutoCommit = false;
674
+ }
675
+
676
+ inline short unlock()
677
+ {
678
+ if (m_db.inSnapshot() || m_db.inTransaction())
679
+ {
680
+ if (m_validCursor)
681
+ m_table->file->unlock_row();
682
+ else
683
+ return 1;
684
+ }else if (m_db.m_inAutoTransaction == this)
685
+ unUse();
686
+ return 0;
687
+ }
688
+
689
+ inline void startStmt()
690
+ {
691
+ m_validCursor = false;
692
+ m_table->file->start_stmt(m_db.m_thd, m_table->reginfo.lock_type);
693
+ }
694
+
695
+ inline void initForHANDLER()
696
+ {
697
+ if (!m_db.m_thd->in_lock_tables)
698
+ {
699
+ m_table->file->init_table_handle_for_HANDLER();
700
+ m_validCursor = false;
701
+ }
702
+ }
703
+
593
704
  };
594
705
 
595
706
  class fieldBitmap
@@ -652,6 +763,17 @@ public:
652
763
  assert(m_table);
653
764
  bitmap_set_bit(m_table->read_set, bit);
654
765
  }
766
+
767
+
768
+ inline MY_BITMAP* getReadBitmap()
769
+ {
770
+ if (m_table)
771
+ return m_table->read_set;
772
+ return NULL;
773
+ }
774
+
775
+ inline bool isUsing() const { return (m_table != NULL); }
776
+
655
777
  };
656
778
 
657
779
  // smart wrapper for exception
@@ -674,10 +796,11 @@ class smartTransction
674
796
  short m_type;
675
797
 
676
798
  public:
677
- smartTransction(database* db, short type = TRN_RECORD_LOCK_SINGLE)
799
+ smartTransction(database* db, short type = TRN_RECORD_LOCK_SINGLE
800
+ , enum_tx_isolation iso = ISO_READ_COMMITTED)
678
801
  : m_db(db)
679
802
  {
680
- m_db->beginTrn(type);
803
+ m_db->beginTrn(type, iso);
681
804
  }
682
805
 
683
806
  void end()
@@ -693,6 +816,21 @@ public:
693
816
  }
694
817
  };
695
818
 
819
+
820
+ struct smartForceConsistantRead
821
+ {
822
+ table* tb;
823
+ inline smartForceConsistantRead(table* t):tb(t)
824
+ {
825
+ tb->m_forceConsistentRead = true;
826
+ }
827
+
828
+ inline ~smartForceConsistantRead()
829
+ {
830
+ tb->m_forceConsistentRead = false;
831
+ }
832
+ };
833
+
696
834
  #define BUILINSERT_SCOPE
697
835
 
698
836
  } // namespace mysql
@@ -21,6 +21,7 @@
21
21
  #include <bzs/netsvc/server/IAppModule.h> //for result value macro.
22
22
  #include <bzs/rtl/exception.h>
23
23
  #include <time.h>
24
+ #include "mysqlThd.h"
24
25
 
25
26
  namespace bzs
26
27
  {
@@ -31,8 +32,48 @@ namespace engine
31
32
  namespace mysql
32
33
  {
33
34
 
35
+
36
+ class smartDbsReopen
37
+ {
38
+ THD* m_thd;
39
+ std::vector<boost::shared_ptr<database> >& m_dbs;
40
+ public:
41
+ static std::string removeName;
42
+
43
+ smartDbsReopen(THD* thd, std::vector<boost::shared_ptr<database> >& dbs) : m_thd(thd), m_dbs(dbs)
44
+ {
45
+ for (size_t i = 0; i < m_dbs.size(); i++)
46
+ {
47
+ if (m_dbs[i])
48
+ {
49
+ m_dbs[i]->use();
50
+ m_dbs[i]->unUseTables(false);
51
+ m_dbs[i]->closeForReopen();
52
+ }
53
+ }
54
+ attachThd(m_thd);
55
+ }
56
+
57
+ ~smartDbsReopen()
58
+ {
59
+ for (size_t i = 0; i < m_dbs.size(); i++)
60
+ {
61
+ if (m_dbs[i])
62
+ {
63
+ if (removeName != m_dbs[i]->name())
64
+ {
65
+ m_dbs[i]->use();
66
+ m_dbs[i]->reopen();
67
+ }
68
+ }
69
+ }
70
+ attachThd(m_thd);
71
+ }
72
+ };
73
+
34
74
  std::string smartDbsReopen::removeName = "";
35
75
 
76
+
36
77
  dbManager::dbManager() : m_autoHandle(0)
37
78
  {
38
79
  }
@@ -62,6 +103,7 @@ void dbManager::checkNewHandle(int newHandle) const
62
103
  THROW_BZS_ERROR_WITH_CODEMSG(1, "Allready exits handle.");
63
104
  }
64
105
 
106
+ // Lock for isSutdown(), called by another thread
65
107
  void dbManager::releaseDatabase(short cid)
66
108
  {
67
109
  boost::mutex::scoped_lock lck(m_mutex);
@@ -143,11 +185,11 @@ database* dbManager::getDatabase(const char* dbname, short cid) const
143
185
  return useDataBase(id);
144
186
  }
145
187
 
146
- table* dbManager::getTable(int hdl, enum_sql_command cmd) const
188
+ table* dbManager::getTable(int hdl, enum_sql_command cmd, engine::mysql::rowLockMode* lck) const
147
189
  {
148
190
  handle* h = getHandle(hdl);
149
191
  if (h && (h->db < (int)m_dbs.size()))
150
- return useDataBase(h->db)->useTable(h->tb, cmd);
192
+ return useDataBase(h->db)->useTable(h->tb, cmd, lck);
151
193
 
152
194
  THROW_BZS_ERROR_WITH_CODEMSG(1, "Invalid handle.");
153
195
  }
@@ -163,7 +205,7 @@ int dbManager::addHandle(int dbid, int tableid, int assignid)
163
205
 
164
206
  int dbManager::ddl_execSql(THD* thd, const std::string& sql_stmt)
165
207
  {
166
- smartDbsReopen reopen(m_dbs);
208
+ smartDbsReopen reopen(thd, m_dbs);
167
209
 
168
210
  thd->clear_error();
169
211
  int result = dispatch_command(COM_QUERY, thd, (char*)sql_stmt.c_str(),