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
@@ -538,7 +538,7 @@ void nsdatabase::reset()
538
538
 
539
539
  if (m_nsimpl->tranCount)
540
540
  {
541
- #ifdef _WIN32
541
+ #if (defined(_WIN32) && defined(_DEBUG))
542
542
  #ifdef LIB_TDCLCPP
543
543
  int ret = MessageBox(NULL, _T("Is an uncompleted transaction aborted?"),
544
544
  NULL, 33);
@@ -565,7 +565,7 @@ void nsdatabase::reset()
565
565
  }
566
566
  }
567
567
  m_nsimpl->lockWaitCount = 10;
568
- m_nsimpl->lockWaitTime = 200;
568
+ m_nsimpl->lockWaitTime = 100;
569
569
  m_nsimpl->tableCount = 0;
570
570
  m_nsimpl->bdfPath[0] = 0x00;
571
571
  if (m_btrcallid)
@@ -581,10 +581,10 @@ void nsdatabase::reset()
581
581
  m_btrcallid = getBtrvEntryPoint();
582
582
  }
583
583
 
584
- void nsdatabase::beginSnapshot()
584
+ void nsdatabase::beginSnapshot(short bias)
585
585
  {
586
586
  if (m_nsimpl->snapShotCount == 0)
587
- m_stat = m_btrcallid(TD_BEGIN_SHAPSHOT, NULL, NULL, NULL, NULL, 0, 0,
587
+ m_stat = m_btrcallid(TD_BEGIN_SHAPSHOT + bias, NULL, NULL, NULL, NULL, 0, 0,
588
588
  m_nsimpl->clientID);
589
589
  m_nsimpl->snapShotCount++;
590
590
  }
@@ -45,10 +45,12 @@ namespace client
45
45
  class dbdef;
46
46
  class nstable;
47
47
 
48
+ /** @cond INTERNAL */
48
49
  DLLLIB void setBtrvEntryPoint(BTRCALLID_PTR p);
49
50
  DLLLIB BTRCALLID_PTR getBtrvEntryPoint();
50
51
  DLLLIB void setTrnsctdEntryPoint(BTRCALLID_PTR p);
51
52
  DLLLIB BTRCALLID_PTR getTrnsctdEntryPoint();
53
+ /** @endcond */
52
54
 
53
55
  class DLLLIB nsdatabase
54
56
  {
@@ -101,12 +103,12 @@ public:
101
103
  virtual void dropTable(const _TCHAR* uri);
102
104
  void rename(const _TCHAR* oldUri, const _TCHAR* newUri);
103
105
  void swapTablename(const _TCHAR* uri1, const _TCHAR* uri2);
104
- void beginTrn(short bias = LOCK_SINGLE_NOWAIT + PARALLEL_TRN +
106
+ void beginTrn(short bias = SINGLELOCK_READ_COMMITED +
105
107
  NOWAIT_WRITE); // NoWit SingleLock
106
108
  // ���s�g�����U�N�V����
107
109
  void endTrn();
108
110
  void abortTrn();
109
- void beginSnapshot();
111
+ void beginSnapshot(short bias = CONSISTENT_READ);
110
112
  void endSnapshot();
111
113
  short_td tdapErr(HWND hWnd, _TCHAR* retbuf = NULL);
112
114
  bool useLongFilename();
@@ -51,7 +51,7 @@ struct nstimpl
51
51
  nstimpl()
52
52
  : refCount(1), bulkIns(NULL), mode(0), shared(false), isOpen(false)
53
53
  {
54
- posblk[0] = 0x00;
54
+ memset(posblk, 0 ,POS_BLOCK_SIZE);
55
55
  }
56
56
  int refCount;
57
57
  bulkInsert* bulkIns;
@@ -121,8 +121,11 @@ _TCHAR* nstable::getErrorMessage(int errorCode, _TCHAR* buf, size_t size)
121
121
  KyeNum
122
122
  - -1 = Unlock the record that specified by bm in multi records.
123
123
  - -2 = Unlock all records
124
- - �{ = Unlock single record.
125
- */
124
+ - �{ = Unlock single record.
125
+ (Trasnactd : in-snapshot current record. Single locked somewhere one record
126
+ : bm and keynumber are ingored.
127
+ )
128
+ */
126
129
  void nstable::unlock(bookmark_td bm)
127
130
  {
128
131
  void* db = m_pdata;
@@ -18,8 +18,8 @@
18
18
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
19
  02111-1307, USA.
20
20
  ================================================================= */
21
- #include <bzs/env/tstring.h>
22
21
  #include <bzs/db/protocol/tdap/tdapcapi.h>
22
+ #include <bzs/env/tstring.h>
23
23
  #include <bzs/db/protocol/tdap/tdapSchema.h>
24
24
  #include <bzs/rtl/exception.h>
25
25
  #include "export.h"
@@ -3,7 +3,7 @@
3
3
  #define BZS_DB_PROTOCOL_TDAP_CLIENT_POOLEDDATABASEMANAGER_H
4
4
 
5
5
  /* =================================================================
6
- Copyright (C) 20014 BizStation Corp All rights reserved.
6
+ Copyright (C) 2014 BizStation Corp All rights reserved.
7
7
 
8
8
  This program is free software; you can redistribute it and/or
9
9
  modify it under the terms of the GNU General Public License
@@ -32,7 +32,7 @@ namespace tdap
32
32
  {
33
33
  namespace client
34
34
  {
35
-
35
+ /** @cond INTERNAL */
36
36
  class xaTransaction
37
37
  {
38
38
  std::vector<dbmanager_ptr> m_dbs;
@@ -47,14 +47,21 @@ public:
47
47
  int ref = m_dbs[i].use_count();
48
48
  m_dbs.erase(m_dbs.begin() + i);
49
49
  if (ref == 2)
50
- releaseConnection(&cpool);
50
+ releaseConnection(&cpool);// Notify release
51
51
  }
52
52
  }
53
53
 
54
54
  void beginTrn(short bias)
55
55
  {
56
56
  for (size_t i = 0; i < m_dbs.size(); ++i)
57
+ {
57
58
  m_dbs[i]->beginTrn(bias);
59
+ if (m_dbs[i]->stat())
60
+ {
61
+ abortTrn();
62
+ nstable::throwError(m_dbs[i]->uri(), m_dbs[i]->stat());
63
+ }
64
+ }
58
65
  }
59
66
 
60
67
  void endTrn()
@@ -69,6 +76,7 @@ public:
69
76
  m_dbs[i]->abortTrn();
70
77
  }
71
78
  };
79
+ /** @endcond */
72
80
 
73
81
  /*
74
82
  --------------------------------------
@@ -116,7 +124,6 @@ public:
116
124
  {
117
125
  m_db.reset();
118
126
  m_xa.unUse();
119
- // releaseConnection(&cpool);
120
127
  m_inUse = false;
121
128
  }
122
129
 
@@ -144,7 +151,7 @@ public:
144
151
 
145
152
  inline int enableTrn() { return m_db->enableTrn(); }
146
153
 
147
- inline void beginSnapshot() { m_db->beginSnapshot(); }
154
+ inline void beginSnapshot(short bias = CONSISTENT_READ) { m_db->beginSnapshot(bias); }
148
155
 
149
156
  inline void endSnapshot() { m_db->endSnapshot(); }
150
157
 
@@ -155,13 +162,17 @@ public:
155
162
  inline static void setMaxConnections(int maxWorkerNum)
156
163
  {
157
164
  cpool.setMaxConnections(maxWorkerNum);
158
- };
159
- inline static int maxConnections() { return cpool.maxConnections(); };
165
+ }
166
+
167
+ inline static int maxConnections() { return cpool.maxConnections(); }
168
+
160
169
  inline static void reserve(size_t size, const connectParams& param)
161
170
  {
162
171
  cpool.reserve(size, param);
163
172
  }
164
- // inline static bool reset(int waitSec=5){return cpool.reset(waitSec);}
173
+
174
+ inline int usingCount() const { return cpool.usingCount(); }
175
+
165
176
  };
166
177
 
167
178
  } // namespace client
@@ -43,22 +43,23 @@ struct sortDescription
43
43
 
44
44
  class recordsetSorter
45
45
  {
46
- const std::vector<sortDescription>& m_sortDesc;
47
-
46
+ const sortDescription* m_begin;
47
+ const sortDescription* m_end;
48
48
  public:
49
- recordsetSorter(std::vector<sortDescription>& sortDesc)
50
- : m_sortDesc(sortDesc)
49
+
50
+ recordsetSorter(sortDescription* begin, sortDescription* end)
51
+ : m_begin(begin), m_end(end)
51
52
  {
52
53
  }
54
+
53
55
  bool operator()(const row_ptr& l, const row_ptr r) const
54
56
  {
55
- std::vector<sortDescription>::const_iterator it = m_sortDesc.begin();
56
- while (it != m_sortDesc.end())
57
+ const sortDescription* it = m_begin;
58
+ while (it != m_end)
57
59
  {
58
- int ret = (*l)[(*it).index].comp((*r)[(*it).index], 0);
60
+ int ret = (*l)[it->index].comp((*r)[it->index], 0);
59
61
  if (ret)
60
- return ((*it).asc) ? (ret < 0) : (ret > 0);
61
-
62
+ return it->asc ? (ret < 0) : (ret > 0);
62
63
  ++it;
63
64
  }
64
65
  return false;
@@ -75,17 +76,17 @@ class multiRecordAlocatorImple : public multiRecordAlocator
75
76
 
76
77
  public:
77
78
  inline multiRecordAlocatorImple(recordsetImple* rs);
78
- inline void init(size_t recordCount, size_t recordLen, int addType,
79
- const table* tb);
79
+ inline void init(size_t recordCount, size_t recordLen,
80
+ int addType, const table* tb);
81
+ inline unsigned char* allocBlobBlock(size_t size);
80
82
  inline unsigned char* ptr(size_t row, int stat);
81
83
  inline void setRowOffset(int v) { m_rowOffset = v; }
82
84
  inline void setJoinType(int v) { m_addType = v; }
83
85
  inline void setInvalidRecord(size_t row, bool v);
84
86
  inline void setCurFirstFiled(int v) { m_curFirstFiled = v; }
85
- inline void
86
- setJoinRowMap(const std::vector<std::vector<int> >* v /*, size_t size*/)
87
+ inline void setJoinRowMap(const std::vector<std::vector<int> >* v)
87
88
  {
88
- m_joinRowMap = v; /*m_joinMapSize = size;*/
89
+ m_joinRowMap = v;
89
90
  }
90
91
  inline const std::vector<std::vector<int> >* joinRowMap() const
91
92
  {
@@ -115,13 +116,24 @@ class recordsetImple
115
116
 
116
117
  public:
117
118
  typedef std::vector<row_ptr>::iterator iterator;
118
-
119
+ typedef row_ptr item_type;
119
120
  private:
121
+ unsigned char* allocBlobBlock(size_t size)
122
+ {
123
+ autoMemory* am = autoMemory::create();
124
+ am->addref();
125
+ am->setParams(NULL, size, 0, true);
126
+ m_memblock.push_back(boost::shared_ptr<autoMemory>(am, boost::bind(&autoMemory::release, _1)));
127
+ return am->ptr;
128
+ }
129
+
120
130
  void registerMemoryBlock(unsigned char* ptr, size_t size, size_t recordLen,
121
131
  int addtype, const table* tb = NULL)
122
132
  {
123
- autoMemory* am = new autoMemory(ptr, size, 0, true);
124
- m_memblock.push_back(boost::shared_ptr<autoMemory>(am));
133
+ autoMemory* am = autoMemory::create();
134
+ am->addref();
135
+ am->setParams(ptr, size, 0, true);
136
+ m_memblock.push_back(boost::shared_ptr<autoMemory>(am, boost::bind(&autoMemory::release, _1)));
125
137
  unsigned char* p = am->ptr;
126
138
  // copy fileds
127
139
  if (addtype & mra_nextrows)
@@ -133,7 +145,6 @@ private:
133
145
  }
134
146
  else
135
147
  {
136
- // assert(tb);
137
148
  m_joinRows = 0;
138
149
  m_mra->setRowOffset(0);
139
150
  m_mra->setCurFirstFiled((int)m_fds->size());
@@ -156,7 +167,7 @@ private:
156
167
  {
157
168
  // Join optimazing
158
169
  const std::vector<std::vector<int> >* jmap = m_mra->joinRowMap();
159
-
170
+ autoMemory* ama = autoMemory::create((int)rows);
160
171
  if (jmap)
161
172
  {
162
173
  // At Join that if some base records reference to a joined
@@ -167,15 +178,21 @@ private:
167
178
  {
168
179
  const std::vector<int>& map = (*jmap)[i + m_joinRows];
169
180
  for (int j = 0; j < (int)map.size(); ++j)
170
- m_recordset[map[j]]->setRecordData(
181
+ {
182
+ autoMemory* a = ama + i;
183
+ m_recordset[map[j]]->setRecordData(a,
171
184
  p + recordLen * i, 0, am->endFieldIndex, false);
185
+ }
172
186
  }
173
187
  }
174
188
  else
175
189
  {
176
190
  for (int i = 0; i < (int)rows; ++i)
177
- m_recordset[i + m_joinRows]->setRecordData(
191
+ {
192
+ autoMemory* a = ama + i;
193
+ m_recordset[i + m_joinRows]->setRecordData(a,
178
194
  p + recordLen * i, 0, am->endFieldIndex, false);
195
+ }
179
196
  }
180
197
  m_joinRows += rows;
181
198
  }
@@ -183,26 +200,24 @@ private:
183
200
  { // create new record
184
201
  size_t reserveSize = m_recordset.size() + rows;
185
202
  m_recordset.reserve(reserveSize);
203
+ memoryRecord* rec = memoryRecord::create(*m_fds, (int)rows);
204
+ autoMemory* ama = autoMemory::create((int)rows);
186
205
  for (int i = 0; i < (int)rows; ++i)
187
206
  {
188
- row_ptr rec(memoryRecord::create(*m_fds),
189
- &memoryRecord::release);
190
- rec->setRecordData(p + recordLen * i, 0, am->endFieldIndex,
207
+ autoMemory* a = ama + i;
208
+ rec[i].setRecordData(a, p + recordLen * i, 0, am->endFieldIndex,
191
209
  false);
192
- m_recordset.push_back(rec);
210
+ push_back(&rec[i]);
193
211
  }
194
212
  }
195
213
  }
196
214
 
197
- void makeSortFields(const _TCHAR* name,
198
- std::vector<sortDescription>& sortDesc, bool asc = true)
215
+ void makeSortFields(const _TCHAR* name, sortDescription* sd, bool asc = true)
199
216
  {
200
- sortDescription sd;
201
- sd.index = m_fds->indexByName(name);
202
- if (sd.index == -1)
217
+ sd->index = m_fds->indexByName(name);
218
+ if (sd->index == -1)
203
219
  THROW_BZS_ERROR_WITH_MSG(_T("orderBy:Invalid field name"));
204
- sd.asc = asc;
205
- sortDesc.push_back(sd);
220
+ sd->asc = asc;
206
221
  }
207
222
 
208
223
  int getMemBlockIndex(unsigned char* ptr) const
@@ -221,13 +236,14 @@ private:
221
236
  void duplicateRow(int row, int count)
222
237
  {
223
238
  row_ptr& r = m_recordset[row];
224
- memoryRecord* p = dynamic_cast<memoryRecord*>(r.get());
225
-
239
+ memoryRecord* p = dynamic_cast<memoryRecord*>(r);
226
240
  m_recordset.reserve(m_recordset.size() + count);
227
- m_recordset.insert(m_recordset.begin() + row, count, row_ptr());
241
+ memoryRecord* rec = memoryRecord::create(*p, count);
228
242
  for (int i = 0; i < count; ++i)
229
- m_recordset[i + row].reset(new memoryRecord(*p),
230
- &memoryRecord::release);
243
+ {
244
+ rec[i].addref();
245
+ m_recordset.insert(m_recordset.begin() + row + i, &rec[i]);
246
+ }
231
247
  }
232
248
 
233
249
  public:
@@ -238,7 +254,16 @@ public:
238
254
  m_mra.reset(new multiRecordAlocatorImple(this));
239
255
  }
240
256
 
241
- inline ~recordsetImple() {}
257
+ inline recordsetImple(const recordsetImple& r)
258
+ : m_fds(r.m_fds),m_mra(r.m_mra), m_recordset(r.m_recordset),
259
+ m_memblock(r.m_memblock), m_unionFds(r.m_unionFds),
260
+ m_joinRows(r.m_joinRows), m_uniqueReadMaxField(r.m_uniqueReadMaxField)
261
+ {
262
+ for (size_t i = 0; i < m_recordset.size(); ++i)
263
+ m_recordset[i]->addref();
264
+ }
265
+
266
+ inline ~recordsetImple() { clearRecords(); }
242
267
 
243
268
  inline void checkIndex(size_t index)
244
269
  {
@@ -246,6 +271,23 @@ public:
246
271
  THROW_BZS_ERROR_WITH_MSG(_T("Invalid row index of recordset."));
247
272
  }
248
273
 
274
+ inline recordsetImple& operator=(const recordsetImple& r)
275
+ {
276
+ if (this != &r)
277
+ {
278
+ m_fds = r.m_fds;
279
+ m_mra = r.m_mra;
280
+ m_recordset = r.m_recordset;
281
+ m_memblock = r.m_memblock;
282
+ m_unionFds = r.m_unionFds;
283
+ m_joinRows = r.m_joinRows;
284
+ m_uniqueReadMaxField = r.m_uniqueReadMaxField;
285
+ for (size_t i = 0; i < m_recordset.size(); ++i)
286
+ m_recordset[i]->addref();
287
+ }
288
+ return *this;
289
+ }
290
+
249
291
  /* This clone is deep copy.
250
292
  But text and blob field data memory are shared.
251
293
  */
@@ -257,33 +299,68 @@ public:
257
299
  p->m_unionFds = m_unionFds;
258
300
  p->m_fds.reset(m_fds->clone(), boost::bind(&fielddefs::release, _1));
259
301
 
260
- std::vector<__int64> offsets;
261
- for (int i = 0; i < (int)m_memblock.size(); ++i)
302
+ std::vector<size_t> offsets;
303
+ if (m_memblock.size())
262
304
  {
263
- autoMemory* am = new autoMemory(m_memblock[i]->ptr,
264
- m_memblock[i]->size, 0, true);
265
- *am->endFieldIndex = *m_memblock[i]->endFieldIndex;
266
- p->m_memblock.push_back(boost::shared_ptr<autoMemory>(am));
267
- offsets.push_back((__int64)(am->ptr - m_memblock[i]->ptr));
305
+ autoMemory* ama = autoMemory::create((int)m_memblock.size());
306
+ for (int i = 0; i < (int)m_memblock.size(); ++i)
307
+ {
308
+ autoMemory* am = ama + i;
309
+ am->addref();
310
+ am->setParams(m_memblock[i]->ptr, m_memblock[i]->size, 0, true);
311
+ *am->endFieldIndex = *m_memblock[i]->endFieldIndex;
312
+ p->m_memblock.push_back(boost::shared_ptr<autoMemory>(am, boost::bind(&autoMemory::release, _1)));
313
+ offsets.push_back((am->ptr - m_memblock[i]->ptr));
314
+ }
268
315
  }
269
-
270
- for (int i = 0; i < (int)m_recordset.size(); ++i)
316
+ if (m_recordset.size())
271
317
  {
272
- memoryRecord* row =
273
- dynamic_cast<memoryRecord*>(m_recordset[i].get());
274
- memoryRecord* mr = memoryRecord::create(*p->m_fds);
275
- row_ptr rec(mr, &memoryRecord::release);
276
- p->m_recordset.push_back(rec);
277
-
278
- for (int j = 0; j < (int)row->memBlockSize(); ++j)
318
+ p->m_recordset.reserve(m_recordset.size());
319
+ memoryRecord* recs = memoryRecord::create(*p->m_fds, (int)m_recordset.size());
320
+ int amindex = 0;
321
+ for (int i = 0; i < (int)m_recordset.size(); ++i)
322
+ {
323
+ memoryRecord* row = dynamic_cast<memoryRecord*>(m_recordset[i]);
324
+ amindex += (int)row->memBlockSize();
325
+ }
326
+ autoMemory* amar = autoMemory::create(amindex);
327
+ amindex = 0;
328
+ std::vector<short> blobs;
329
+ std::vector<short> offsetIndex;
330
+ for (int j = 0; j < (int)m_fds->size(); ++j)
331
+ {
332
+ if (m_fds->operator[](j).blobLenBytes())
333
+ {
334
+ blobs.push_back((short)j);
335
+ unsigned char* p = (unsigned char*)(*m_recordset[0])[j].ptr()
336
+ + m_fds->operator[](j).blobLenBytes();
337
+ short index = (short)getMemBlockIndex(p);
338
+ offsetIndex.push_back(index);
339
+ }
340
+ }
341
+ for (int i = 0; i < (int)m_recordset.size(); ++i)
279
342
  {
280
- const autoMemory& mb = row->memBlock(j);
281
- int index = getMemBlockIndex(mb.ptr);
343
+ memoryRecord* row =
344
+ dynamic_cast<memoryRecord*>(m_recordset[i]);
345
+ memoryRecord* mr = recs + i;
346
+ p->push_back(mr);
347
+ mr->m_invalidRecord = row->m_invalidRecord;
348
+ for (int j = 0; j < (int)row->memBlockSize(); ++j)
349
+ {
350
+ const autoMemory& mb = row->memBlock(j);
351
+ int index = getMemBlockIndex(mb.ptr);
282
352
  #pragma warn -8072
283
- unsigned char* ptr = mb.ptr + offsets[index];
353
+ unsigned char* ptr = mb.ptr + offsets[index];
284
354
  #pragma warn .8072
285
- const boost::shared_ptr<autoMemory>& am = p->m_memblock[index];
286
- mr->setRecordData(ptr, mb.size, am->endFieldIndex, mb.owner);
355
+ autoMemory* a = amar + amindex;
356
+ const boost::shared_ptr<autoMemory>& am = p->m_memblock[index];
357
+ mr->setRecordData(a, ptr, mb.size, am->endFieldIndex, mb.owner);
358
+ ++amindex;
359
+ }
360
+
361
+ for (int j = 0; j < (int)blobs.size(); ++j)
362
+ row->getFieldNoCheck(blobs[j])
363
+ .offsetBlobPtr(offsets[offsetIndex[j]]);
287
364
  }
288
365
  }
289
366
  return p;
@@ -293,6 +370,15 @@ public:
293
370
 
294
371
  inline void clearRecords()
295
372
  {
373
+ if (m_recordset.size())
374
+ {
375
+ if (!m_recordset[0]->tryFastRelease((int)m_recordset.size()))
376
+ {
377
+ for (int i = (int)m_recordset.size() - 1; i >= 0; --i)
378
+ m_recordset[i]->release();
379
+ }
380
+ }
381
+
296
382
  m_recordset.clear();
297
383
  m_uniqueReadMaxField = 0;
298
384
  }
@@ -311,21 +397,21 @@ public:
311
397
 
312
398
  inline row& operator[](size_t index) const
313
399
  {
314
- return *m_recordset[index].get();
400
+ return *m_recordset[index];
315
401
  }
316
402
 
317
403
  inline row& first() const
318
404
  {
319
405
  if (m_recordset.size() == 0)
320
406
  THROW_BZS_ERROR_WITH_MSG(_T("Invalid index of recordset."));
321
- return *m_recordset[0].get();
407
+ return *m_recordset[0];
322
408
  }
323
409
 
324
410
  inline row& last() const
325
411
  {
326
412
  if (m_recordset.size() == 0)
327
413
  THROW_BZS_ERROR_WITH_MSG(_T("Invalid index of recordset."));
328
- return *m_recordset[m_recordset.size() - 1].get();
414
+ return *m_recordset[m_recordset.size() - 1];
329
415
  }
330
416
 
331
417
  inline recordsetImple& top(recordsetImple& c, int n) const
@@ -344,12 +430,20 @@ public:
344
430
 
345
431
  inline iterator erase(size_t index)
346
432
  {
347
- return m_recordset.erase(m_recordset.begin() + index);
433
+ return erase(m_recordset.begin() + index);
348
434
  }
349
435
 
350
- inline iterator erase(const iterator& it) { return m_recordset.erase(it); }
436
+ inline iterator erase(const iterator& it)
437
+ {
438
+ m_recordset[it - m_recordset.begin()]->release();
439
+ return m_recordset.erase(it);
440
+ }
351
441
 
352
- inline void push_back(row_ptr r) { m_recordset.push_back(r); };
442
+ inline void push_back(row_ptr r)
443
+ {
444
+ r->addref();
445
+ m_recordset.push_back(r);
446
+ }
353
447
 
354
448
  inline size_t size() const { return m_recordset.size(); }
355
449
 
@@ -420,43 +514,45 @@ public:
420
514
  const _TCHAR* name5 = NULL, const _TCHAR* name6 = NULL,
421
515
  const _TCHAR* name7 = NULL, const _TCHAR* name8 = NULL)
422
516
  {
423
- if (m_recordset.size())
517
+ if (m_recordset.size() > 1)
424
518
  {
425
- std::vector<sortDescription> sds;
426
- makeSortFields(name1, sds, true);
519
+ sortDescription sds[9];
520
+ sortDescription* sd = &sds[0];
521
+ makeSortFields(name1, sd, true);
427
522
  if (name2)
428
- makeSortFields(name2, sds, true);
523
+ makeSortFields(name2, ++sd, true);
429
524
  if (name3)
430
- makeSortFields(name3, sds, true);
525
+ makeSortFields(name3, ++sd, true);
431
526
  if (name4)
432
- makeSortFields(name4, sds, true);
527
+ makeSortFields(name4, ++sd, true);
433
528
  if (name5)
434
- makeSortFields(name5, sds, true);
529
+ makeSortFields(name5, ++sd, true);
435
530
  if (name6)
436
- makeSortFields(name6, sds, true);
531
+ makeSortFields(name6, ++sd, true);
437
532
  if (name7)
438
- makeSortFields(name7, sds, true);
533
+ makeSortFields(name7, ++sd, true);
439
534
  if (name8)
440
- makeSortFields(name8, sds, true);
441
- std::sort(begin(), end(), recordsetSorter(sds));
535
+ makeSortFields(name8, ++sd, true);
536
+ std::sort(begin(), end(), recordsetSorter(&sds[0], ++sd));
442
537
  }
443
538
  return *this;
444
539
  }
445
540
 
446
541
  inline recordsetImple& orderBy(const sortFields& orders)
447
542
  {
448
- if (m_recordset.size())
543
+ if (m_recordset.size() > 1)
449
544
  {
450
- std::vector<sortDescription> sds;
451
-
545
+ if (orders.size() > 8)
546
+ THROW_BZS_ERROR_WITH_MSG(_T("orderBy:Too many keys"));
547
+ sortDescription sds[9];
452
548
  for (int i = 0; i < (int)orders.size(); ++i)
453
- makeSortFields(orders[i].name.c_str(), sds, orders[i].asc);
454
-
455
- std::sort(begin(), end(), recordsetSorter(sds));
549
+ makeSortFields(orders[i].name.c_str(), &sds[i], orders[i].asc);
550
+ std::sort(begin(), end(), recordsetSorter(&sds[0], &sds[orders.size()]));
456
551
  }
457
552
  return *this;
458
553
  }
459
554
 
555
+
460
556
  inline recordsetImple& reverse()
461
557
  {
462
558
  std::reverse(begin(), end());
@@ -466,11 +562,14 @@ public:
466
562
  inline void appendField(const _TCHAR* name, int type, short len)
467
563
  {
468
564
  assert(m_fds->size());
565
+
469
566
  fielddef fd((*m_fds)[0]);
470
567
  fd.len = len;
471
568
  fd.pos = 0;
472
569
  fd.type = type;
473
570
  fd.setName(name);
571
+ if (fd.blobLenBytes())
572
+ THROW_BZS_ERROR_WITH_MSG(_T("Can not append Blob or Text field."));
474
573
  m_fds->push_back(&fd);
475
574
  for (int i = 0; i < (int)m_unionFds.size(); ++i)
476
575
  m_unionFds[i]->push_back(&fd);
@@ -485,7 +584,7 @@ public:
485
584
  m_recordset.reserve(m_recordset.size() + r.size());
486
585
  m_unionFds.push_back(r.m_fds);
487
586
  for (size_t i = 0; i < r.size(); ++i)
488
- m_recordset.push_back(r.m_recordset[i]);
587
+ push_back(r.m_recordset[i]);
489
588
  for (size_t i = 0; i < r.m_memblock.size(); ++i)
490
589
  m_memblock.push_back(r.m_memblock[i]);
491
590
  return *this;
@@ -526,6 +625,11 @@ inline void multiRecordAlocatorImple::init(size_t recordCount, size_t recordLen,
526
625
  addType | m_addType, tb);
527
626
  }
528
627
 
628
+ unsigned char* multiRecordAlocatorImple::allocBlobBlock(size_t size)
629
+ {
630
+ return m_rs->allocBlobBlock(size);
631
+ }
632
+
529
633
  inline unsigned char* multiRecordAlocatorImple::ptr(size_t row, int stat)
530
634
  {
531
635
  int col = (stat == mra_current_block) ? m_curFirstFiled : 0;
@@ -556,20 +660,22 @@ inline void multiRecordAlocatorImple::removeLastMemBlock(int row)
556
660
  (*m_rs)[row].removeLastMemBlock();
557
661
  }
558
662
 
559
- template <> inline recordsetImple::iterator begin(recordsetImple& m)
663
+ /*template <> */inline recordsetImple::iterator begin(recordsetImple& m)
560
664
  {
561
665
  return m.begin();
562
666
  }
563
- template <> inline recordsetImple::iterator end(recordsetImple& m)
667
+ /*template <> */inline recordsetImple::iterator end(recordsetImple& m)
564
668
  {
565
669
  return m.end();
566
670
  }
567
- template <> inline void push_back(recordsetImple& m, row_ptr c)
671
+
672
+ /* Called from trdormapi.h : mdlsHandler::addContainer() */
673
+ inline void push_back(recordsetImple& m, row_ptr c)
568
674
  {
569
675
  }
570
676
 
571
677
  /* for groupby */
572
- template <> inline void clear(recordsetImple& m)
678
+ inline void clear(recordsetImple& m)
573
679
  {
574
680
  return m.clearRecords();
575
681
  }
@@ -582,6 +688,7 @@ resolvKeyValue(recordsetImple& m, const std::_tstring& name, bool noexception)
582
688
  return m.resolvKeyValue(name, noexception);
583
689
  }
584
690
 
691
+ /* Called from trdormapi.h : mdlsHandler::operator() */
585
692
  inline row* create(recordsetImple& m, int)
586
693
  {
587
694
  return NULL;