transactd 2.2.0 → 2.3.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +6 -6
  3. data/README +20 -18
  4. data/README-JA +19 -17
  5. data/RELEASE_NOTE +144 -0
  6. data/RELEASE_NOTE-JA +153 -0
  7. data/bin/common/tdclc_32_2_3.dll +0 -0
  8. data/bin/common/tdclc_64_2_3.dll +0 -0
  9. data/build/common/get_ruby_path.cmake +1 -1
  10. data/build/swig/ruby/ruby.swg +10 -9
  11. data/build/swig/ruby/tdclrb_wrap.cpp +1416 -561
  12. data/build/swig/tdcl.i +30 -3
  13. data/build/tdclc/tdclc.cbproj +1 -1
  14. data/build/tdclc/tdclc.rc +4 -4
  15. data/build/tdclcpp/BUILDNUMBER.txt +1 -0
  16. data/build/tdclcpp/tdclcpp.rc +4 -4
  17. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  18. data/build/tdclrb/BUILDNUMBER.txt +1 -0
  19. data/build/tdclrb/tdclrb.rc +4 -4
  20. data/source/bzs/db/engine/mysql/database.cpp +85 -41
  21. data/source/bzs/db/engine/mysql/database.h +35 -5
  22. data/source/bzs/db/engine/mysql/mysqlInternal.h +189 -37
  23. data/source/bzs/db/engine/mysql/mysqlThd.cpp +21 -21
  24. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +11 -0
  25. data/source/bzs/db/protocol/tdap/client/activeTable.h +1 -1
  26. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +11 -4
  27. data/source/bzs/db/protocol/tdap/client/client.h +30 -1
  28. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +2 -1
  29. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +35 -5
  30. data/source/bzs/db/protocol/tdap/client/field.cpp +100 -51
  31. data/source/bzs/db/protocol/tdap/client/field.h +7 -7
  32. data/source/bzs/db/protocol/tdap/client/filter.h +20 -6
  33. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +337 -58
  34. data/source/bzs/db/protocol/tdap/client/groupQuery.h +56 -13
  35. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +83 -5
  36. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
  37. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +2 -2
  38. data/source/bzs/db/protocol/tdap/client/nsTable.h +2 -1
  39. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +20 -6
  40. data/source/bzs/db/protocol/tdap/client/recordset.cpp +7 -0
  41. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +8 -4
  42. data/source/bzs/db/protocol/tdap/client/request.h +11 -1
  43. data/source/bzs/db/protocol/tdap/client/serializer.cpp +40 -2
  44. data/source/bzs/db/protocol/tdap/client/serializer.h +4 -2
  45. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +1 -0
  46. data/source/bzs/db/protocol/tdap/client/stringConverter.h +4 -4
  47. data/source/bzs/db/protocol/tdap/client/table.cpp +124 -71
  48. data/source/bzs/db/protocol/tdap/client/table.h +8 -7
  49. data/source/bzs/db/protocol/tdap/client/trdormapi.h +33 -1
  50. data/source/bzs/db/protocol/tdap/fieldComp.h +1 -1
  51. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +3 -1
  52. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +20 -4
  53. data/source/bzs/db/protocol/tdap/mysql/request.h +14 -0
  54. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +132 -69
  55. data/source/bzs/db/protocol/tdap/tdapRequest.h +18 -4
  56. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +32 -22
  57. data/source/bzs/db/protocol/tdap/tdapSchema.h +69 -4
  58. data/source/bzs/db/protocol/tdap/tdapcapi.h +13 -5
  59. data/source/bzs/db/protocol/tdap/uri.h +4 -4
  60. data/source/bzs/db/transactd/transactd.cpp +6 -5
  61. data/source/bzs/env/crosscompile.cpp +17 -0
  62. data/source/bzs/env/crosscompile.h +4 -1
  63. data/source/bzs/env/mbcswchrLinux.cpp +3 -0
  64. data/source/bzs/example/deleteRecords.cpp +13 -0
  65. data/source/bzs/example/deleteRecords_c.cpp +8 -1
  66. data/source/bzs/example/insertRecords.cpp +14 -0
  67. data/source/bzs/example/insertRecords_c.cpp +8 -1
  68. data/source/bzs/example/ormap_c.cpp +8 -1
  69. data/source/bzs/example/queryData.cpp +92 -2
  70. data/source/bzs/example/queryData.h +3 -1
  71. data/source/bzs/example/readRecords.cpp +13 -0
  72. data/source/bzs/example/readRecords_c.cpp +8 -1
  73. data/source/bzs/example/updateRecords.cpp +13 -0
  74. data/source/bzs/example/updateRecords_c.cpp +8 -1
  75. data/source/bzs/example/update_with_transaction.cpp +13 -0
  76. data/source/bzs/example/update_with_transaction_c.cpp +8 -1
  77. data/source/bzs/example/useORMRecord.cpp +9 -3
  78. data/source/bzs/netsvc/client/iconnection.h +8 -0
  79. data/source/bzs/netsvc/client/tcpClient.cpp +61 -16
  80. data/source/bzs/netsvc/client/tcpClient.h +430 -214
  81. data/source/bzs/netsvc/server/serverPipe.cpp +2 -2
  82. data/source/bzs/test/tdclphp/transactd_Test.php +115 -19
  83. data/source/bzs/test/tdclphp/transactd_blob_Test.php +33 -5
  84. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +21 -3
  85. data/source/bzs/test/tdclphp/transactd_pool_Test.php +17 -3
  86. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +26 -8
  87. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +13 -6
  88. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +14 -8
  89. data/source/bzs/test/tdclrb/transactd_spec.rb +117 -27
  90. data/source/bzs/test/transactdBench/scaling_bench.cpp +5 -5
  91. data/source/bzs/test/transactdBench/workerBase.h +2 -2
  92. data/source/bzs/test/trdclengn/test_trdclengn.cpp +898 -51
  93. data/source/global/tdclatl/Database.cpp +12 -0
  94. data/source/global/tdclatl/Database.h +4 -0
  95. data/source/global/tdclatl/FieldDef.cpp +19 -0
  96. data/source/global/tdclatl/FieldDef.h +4 -0
  97. data/source/global/tdclatl/FieldDefs.cpp +14 -16
  98. data/source/global/tdclatl/GroupQuery.cpp +21 -16
  99. data/source/global/tdclatl/GroupQuery.h +1 -1
  100. data/source/global/tdclatl/QueryBase.cpp +14 -0
  101. data/source/global/tdclatl/QueryBase.h +2 -0
  102. data/source/global/tdclatl/Record.cpp +41 -10
  103. data/source/global/tdclatl/Record.h +1 -1
  104. data/source/global/tdclatl/Recordset.cpp +117 -31
  105. data/source/global/tdclatl/Recordset.h +6 -5
  106. data/source/global/tdclatl/Table.cpp +24 -28
  107. data/source/global/tdclatl/Table.h +3 -4
  108. data/source/global/tdclatl/activeTable.cpp +149 -103
  109. data/source/global/tdclatl/activeTable.h +1 -1
  110. data/source/global/tdclatl/tdclatl.idl +38 -18
  111. data/transactd.gemspec +1 -1
  112. metadata +8 -4
  113. data/bin/common/tdclc_32_2_2.dll +0 -0
  114. data/bin/common/tdclc_64_2_2.dll +0 -0
@@ -150,28 +150,38 @@ class DLLLIB groupFuncBase : public recordsetQuery
150
150
  {
151
151
  protected:
152
152
  friend class groupQueryImple;
153
+ friend class groupFuncBaseImple;
154
+
155
+ typedef double numeric_type;
153
156
 
154
157
  class groupFuncBaseImple* m_imple;
158
+
159
+ void init(const fielddefs* fdinfo);
160
+ unsigned char* stringResult(int groupIndex) const;
161
+ uchar_td resultType() const;
162
+ ushort_td resultLen() const;
163
+ void operator()(const row_ptr& row, int index, bool insert);
164
+
155
165
  virtual void initResultVariable(int index);
156
166
  virtual void doCalc(const row_ptr& row, int groupIndex);
157
- void init(const fielddefs* fdinfo);
167
+ virtual void doReset();
168
+ virtual void doInit(const fielddefs* fdinfo);
169
+ virtual numeric_type numericResult(int groupIndex) const;
170
+
158
171
 
159
172
  public:
160
- typedef double value_type;
161
173
  groupFuncBase();
162
174
  groupFuncBase(const groupFuncBase& v);
163
- groupFuncBase& operator=(const groupFuncBase& v);
164
175
  groupFuncBase(const fieldNames& targetNames,
165
176
  const _TCHAR* resultName = NULL);
166
177
  virtual ~groupFuncBase();
178
+ groupFuncBase& operator=(const groupFuncBase& v);
167
179
  groupFuncBase& operator=(const recordsetQuery& v);
168
180
  fieldNames& targetNames() const;
169
181
  const _TCHAR* resultName() const;
170
182
  void setResultName(const _TCHAR* v);
171
183
  int resultKey() const;
172
184
  void reset();
173
- void operator()(const row_ptr& row, int index, bool insert);
174
- virtual value_type result(int groupIndex) const;
175
185
  virtual groupFuncBase* clone() = 0;
176
186
  };
177
187
 
@@ -208,11 +218,10 @@ class DLLLIB sum : public groupFuncBase
208
218
  {
209
219
  protected:
210
220
  void doCalc(const row_ptr& row, int index);
211
-
221
+ groupFuncBase* clone();
212
222
  public:
213
223
  sum() {}
214
224
  sum(const fieldNames& targetNames, const _TCHAR* resultName = NULL);
215
- groupFuncBase* clone();
216
225
  static sum* create(const fieldNames& targetNames,
217
226
  const _TCHAR* resultName = NULL);
218
227
  };
@@ -220,26 +229,25 @@ public:
220
229
  class DLLLIB count : public groupFuncBase
221
230
  {
222
231
  protected:
232
+ groupFuncBase* clone();
223
233
  void doCalc(const row_ptr& row, int index);
224
234
 
225
235
  public:
226
236
  count() {}
227
237
  count(const _TCHAR* resultName);
228
- groupFuncBase* clone();
229
238
  static count* create(const _TCHAR* resultName);
230
239
  };
231
240
 
232
241
  class DLLLIB avg : public sum
233
242
  {
234
-
235
243
  void initResultVariable(int index);
236
244
  void doCalc(const row_ptr& row, int index);
237
- value_type result(int index) const;
245
+ numeric_type numericResult(int index) const;
246
+ groupFuncBase* clone();
238
247
 
239
248
  public:
240
249
  avg() {}
241
250
  avg(const fieldNames& targetNames, const _TCHAR* resultName = NULL);
242
- groupFuncBase* clone();
243
251
  static avg* create(const fieldNames& targetNames,
244
252
  const _TCHAR* resultName = NULL);
245
253
  };
@@ -247,13 +255,15 @@ public:
247
255
  #undef min
248
256
  class DLLLIB min : public sum
249
257
  {
258
+ protected:
250
259
  bool m_flag;
251
260
  void doCalc(const row_ptr& row, int index);
261
+ groupFuncBase* clone();
262
+ min& operator=(const min& r);
252
263
 
253
264
  public:
254
265
  min() {}
255
266
  min(const fieldNames& targetNames, const _TCHAR* resultName = NULL);
256
- groupFuncBase* clone();
257
267
  static min* create(const fieldNames& targetNames,
258
268
  const _TCHAR* resultName = NULL);
259
269
  };
@@ -263,15 +273,48 @@ class DLLLIB max : public sum
263
273
  {
264
274
  bool m_flag;
265
275
  void doCalc(const row_ptr& row, int index);
276
+ groupFuncBase* clone();
277
+ max& operator=(const max& r);
266
278
 
267
279
  public:
268
280
  max() {}
269
281
  max(const fieldNames& targetNames, const _TCHAR* resultName = NULL);
270
- groupFuncBase* clone();
271
282
  static max* create(const fieldNames& targetNames,
272
283
  const _TCHAR* resultName = NULL);
273
284
  };
274
285
 
286
+
287
+ class DLLLIB last : public groupFuncBase
288
+ {
289
+ protected:
290
+ void doCalc(const row_ptr& row, int index);
291
+ void doInit(const fielddefs* fdinfo);
292
+ groupFuncBase* clone();
293
+ public:
294
+ last() {}
295
+ last(const fieldNames& targetNames, const _TCHAR* resultName = NULL);
296
+ static last* create(const fieldNames& targetNames,
297
+ const _TCHAR* resultName = NULL);
298
+ };
299
+
300
+
301
+ class DLLLIB first : public last
302
+ {
303
+ bool m_readed;
304
+ protected:
305
+ void doCalc(const row_ptr& row, int index);
306
+ void doReset();
307
+ groupFuncBase* clone();
308
+ first& operator=(const first& r);
309
+ public:
310
+ first() {}
311
+ first(const fieldNames& targetNames, const _TCHAR* resultName = NULL);
312
+ static first* create(const fieldNames& targetNames,
313
+ const _TCHAR* resultName = NULL);
314
+ };
315
+
316
+
317
+
275
318
  } // namespace client
276
319
  } // namespace tdap
277
320
  } // namespace protocol
@@ -31,6 +31,7 @@
31
31
  typedef void* HANDLE;
32
32
  typedef void* HINSTANCE;
33
33
  #endif
34
+ #include <bzs/db/protocol/tdap/tdapRequest.h>
34
35
 
35
36
  #pragma package(smart_init)
36
37
 
@@ -762,20 +763,97 @@ bool nsdatabase::connect(const _TCHAR* URI, bool newConnection)
762
763
 
763
764
  bool nsdatabase::disconnect(const _TCHAR* URI)
764
765
  {
765
- if (isTransactdUri(URI))
766
+ if (!URI || (URI[0] == 0x00) || isTransactdUri(URI))
766
767
  if (!setUseTransactd())
767
768
  return false;
768
769
  uint_td datalen = 0;
769
- char uri_a[MAX_PATH];
770
- const char* p = toServerUri(uri_a, MAX_PATH, URI, isUseTransactd());
771
- m_stat = m_btrcallid(TD_CONNECT, NULL, NULL, &datalen, (void*)p,
772
- (keylen_td)(strlen(p) + 1), LG_SUBOP_DISCONNECT,
770
+
771
+ //Transactd not use uri.
772
+ m_stat = m_btrcallid(TD_CONNECT, NULL, NULL, &datalen, (void*)URI,
773
+ (keylen_td)(_tcslen(URI) + 1), LG_SUBOP_DISCONNECT,
773
774
  clientID());
774
775
  if (m_stat)
775
776
  return false;
776
777
  return true;
777
778
  }
778
779
 
780
+
781
+ bool nsdatabase::disconnectForReconnectTest()
782
+ {
783
+ //Transactd only
784
+ if (!isUseTransactd())
785
+ return false;
786
+
787
+ uint_td datalen = 0;
788
+ m_stat = m_btrcallid(TD_CONNECT, NULL, NULL, &datalen, NULL,
789
+ 0, LG_SUBOP_DISCONNECT_EX,
790
+ clientID());
791
+ if (m_stat)
792
+ return false;
793
+ return true;
794
+ }
795
+
796
+ /* TD_RECONNECT data buffer structure
797
+
798
+ 1 byte keynum
799
+ 1 byte bookmark size
800
+ n byte bookmark
801
+
802
+ */
803
+ void nsdatabase::doReconnect(nstable* tb)
804
+ {
805
+ uint_td datalen = 0;
806
+ char uri_a[MAX_PATH] = { 0x00 };
807
+ tb->abortBulkInsert();
808
+ datalen = tb->buflen();
809
+ tdap::posblk* pb = (tdap::posblk*)tb->posblk();
810
+ char* databuf = new char[datalen];
811
+ databuf[0] = tb->keyNum();
812
+ memcpy(databuf + 1, &pb->bookmarkLen, pb->bookmarkLen + 1);
813
+ const char* p = toServerUri(uri_a, MAX_PATH, tb->uri(), true);
814
+ short offset = (pb->lock) ? ROW_LOCK_X : 0;
815
+ m_stat = m_btrcallid(TD_RECONNECT + offset, pb, databuf, &datalen, (void*)p,
816
+ (keylen_td)(strlen(p) + 1), tb->mode(), clientID());
817
+ delete [] databuf;
818
+ }
819
+
820
+ bool nsdatabase::reconnect()
821
+ {
822
+ //Transactd only
823
+ if (!isUseTransactd())
824
+ return false;
825
+ m_nsimpl->tranCount = 0;
826
+ m_nsimpl->snapShotCount = 0;
827
+
828
+
829
+ uint_td datalen = 0;
830
+ char uri_a[MAX_PATH] = { 0x00 };
831
+ const char* p = toServerUri(uri_a, MAX_PATH, m_nsimpl->bdfPath, true);
832
+ m_stat = m_btrcallid(TD_CONNECT, NULL, NULL, &datalen, (void*)p,
833
+ (keylen_td)(strlen(p) + 1),
834
+ LG_SUBOP_RECONNECT, clientID());
835
+ if (m_stat) return false;
836
+
837
+ //Whole table, restore position.
838
+ nstable* lockedTable = NULL; //This is only one.
839
+ for (int i=0;i<m_nsimpl->tableCount;++i)
840
+ {
841
+ nstable* tb = m_nsimpl->tables[i];
842
+ if (tb && tb->isOpen())
843
+ {
844
+ tdap::posblk* pb = (tdap::posblk*)tb->posblk();
845
+ if (pb->lock)
846
+ lockedTable = tb;
847
+ else
848
+ doReconnect(tb);
849
+ if (m_stat != 0) break;
850
+ }
851
+ }
852
+ if (lockedTable)
853
+ doReconnect(lockedTable);
854
+ return (m_stat == 0);
855
+ }
856
+
779
857
  bool nsdatabase::trnsactionFlushWaitStatus()
780
858
  {
781
859
  bool ret = false;
@@ -77,7 +77,7 @@ protected:
77
77
  bool findTable(nstable* tb);
78
78
  void addref();
79
79
  void internalRelease() { nsdatabase::release(); }
80
-
80
+ void doReconnect(nstable* tb);
81
81
  public:
82
82
  nsdatabase();
83
83
  virtual void release();
@@ -121,6 +121,9 @@ public:
121
121
  void readDatabaseDirectory(_TCHAR* retBuf, uchar_td len);
122
122
  bool connect(const _TCHAR* uri, bool newConnection = false);
123
123
  bool disconnect(const _TCHAR* uri = _T(""));
124
+ bool disconnectForReconnectTest(); //for connection brokn emulate
125
+ bool reconnect();
126
+
124
127
  static const int maxtables = 50;
125
128
  static bool trnsactionFlushWaitStatus();
126
129
  static void setExecCodePage(unsigned int codepage);
@@ -388,10 +388,10 @@ void nstable::doOpen(const _TCHAR* name, char_td mode, const _TCHAR* ownerName)
388
388
  else
389
389
  m_keynum = mode;
390
390
 
391
- char ownerNameBuf[OWNERNAME_SIZE + 1] = { 0x00 };
391
+ char ownerNameBuf[OWNERNAME_SIZE] = { 0x00 };
392
392
  if (NULL != ownerName && 0x00 != ownerName[0])
393
393
  {
394
- const char* p2 = toChar(ownerNameBuf, ownerName, 22);
394
+ const char* p2 = toChar(ownerNameBuf, ownerName, OWNERNAME_SIZE);
395
395
  m_pdata = (void*)p2;
396
396
  m_datalen = (uint_td)strlen(p2) + 1;
397
397
  if (m_datalen > 11)
@@ -56,7 +56,8 @@ public:
56
56
  enum eFindType
57
57
  {
58
58
  findForword,
59
- findBackForword
59
+ findBackForword,
60
+ findContinue
60
61
  };
61
62
  static const bool inkey = true;
62
63
 
@@ -98,9 +98,10 @@ class pooledDbManager : public idatabaseManager
98
98
  dbmanager_ptr m_db;
99
99
  bool m_inUse;
100
100
  xaTransaction m_xa;
101
+ bool m_use_xa;
101
102
 
102
103
  public:
103
- inline pooledDbManager() : m_inUse(false){};
104
+ inline pooledDbManager() : m_inUse(false),m_use_xa(false){};
104
105
 
105
106
  inline pooledDbManager(const connectParams* param) : m_inUse(false)
106
107
  {
@@ -113,6 +114,10 @@ public:
113
114
  unUse();
114
115
  }
115
116
 
117
+ inline bool isUseXa() const {return m_use_xa;}
118
+
119
+ inline void setUseXa(bool v) {m_use_xa = v;}
120
+
116
121
  inline void use(const connectParams* param = NULL)
117
122
  {
118
123
  m_db = cpool.get(param);
@@ -139,15 +144,24 @@ public:
139
144
 
140
145
  inline bool isOpened() const { return m_db->isOpened(); }
141
146
 
142
- inline void setOption(__int64 v) { m_db->setOption(v); };
147
+ inline void setOption(__int64 v) { m_db->setOption(v); }
143
148
 
144
- inline __int64 option() { return m_db->option(); };
149
+ inline __int64 option() { return m_db->option(); }
145
150
 
146
- inline void beginTrn(short bias) { m_xa.beginTrn(bias); };
151
+ inline void beginTrn(short bias)
152
+ {
153
+ (m_use_xa == true) ? m_xa.beginTrn(bias) : m_db->beginTrn(bias);
154
+ }
147
155
 
148
- inline void endTrn() { m_xa.endTrn(); }
156
+ inline void endTrn()
157
+ {
158
+ (m_use_xa == true) ? m_xa.endTrn() : m_db->endTrn();
159
+ }
149
160
 
150
- inline void abortTrn() { m_xa.abortTrn(); }
161
+ inline void abortTrn()
162
+ {
163
+ (m_use_xa == true) ? m_xa.abortTrn() : m_db->abortTrn();
164
+ }
151
165
 
152
166
  inline int enableTrn() { return m_db->enableTrn(); }
153
167
 
@@ -186,6 +186,13 @@ void recordset::appendField(const _TCHAR* name, int type, short len)
186
186
 
187
187
  recordset& recordset::operator+=(const recordset& r)
188
188
  {
189
+ if (r.size() == 0)
190
+ return *this;
191
+ if ((size() == 0) && r.size())
192
+ {
193
+ *this = r;
194
+ return *this;
195
+ }
189
196
  m_imple->operator+=(*r.m_imple);
190
197
  return *this;
191
198
  }
@@ -387,10 +387,13 @@ public:
387
387
 
388
388
  inline void clear()
389
389
  {
390
- clearRecords();
391
- m_fds->clear();
392
- m_unionFds.clear();
393
- m_memblock.clear();
390
+ if (m_memblock.size())
391
+ {
392
+ clearRecords();
393
+ m_fds->clear();
394
+ m_unionFds.clear();
395
+ m_memblock.clear();
396
+ }
394
397
  }
395
398
 
396
399
  inline row_ptr& getRow(size_t index) { return m_recordset[index]; }
@@ -567,6 +570,7 @@ public:
567
570
  assert(m_fds->size());
568
571
 
569
572
  fielddef fd((*m_fds)[0]);
573
+ memset(&fd, 0, sizeof(fielddef));
570
574
  fd.len = len;
571
575
  fd.pos = 0;
572
576
  fd.type = type;
@@ -51,7 +51,6 @@ class request : public bzs::db::protocol::tdap::request,
51
51
  {
52
52
  public:
53
53
  clientID* cid;
54
-
55
54
  request() : bzs::db::protocol::tdap::request(), cid(NULL){};
56
55
 
57
56
  unsigned int onRead(unsigned int size, bzs::netsvc::client::connection* c) // orverride
@@ -123,7 +122,18 @@ public:
123
122
  {
124
123
  memcpy(pbk, p, TD_POSBLK_TRANSMIT_SIZE);
125
124
  p += TD_POSBLK_TRANSMIT_SIZE;
125
+ if (P_MASK_PB_BOOKMARK & paramMask)
126
+ {
127
+ unsigned char len = *((unsigned char*)p);
128
+ // copy sizeByte and bookmark
129
+ pbk->bookmarkLen = len;
130
+ pbk->lock = ((paramMask & P_MASK_PB_LOCKED) != 0);
131
+ memcpy(pbk->bookmark, ++p , len);
132
+ p += len;
133
+ }
126
134
  }
135
+ if (P_MASK_PB_ERASE_BM & paramMask)
136
+ pbk->bookmarkLen = 0;
127
137
 
128
138
  if (P_MASK_DATALEN & paramMask)
129
139
  {
@@ -48,6 +48,8 @@ BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::count, "count");
48
48
  BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::avg, "avg");
49
49
  BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::min, "min");
50
50
  BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::max, "max");
51
+ BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::first, "first");
52
+ BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::last, "last");
51
53
 
52
54
  BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::readStatement,
53
55
  "readStatement");
@@ -63,6 +65,7 @@ BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::reverseOrderStatement,
63
65
  "reverseOrderStatement");
64
66
 
65
67
  BOOST_CLASS_VERSION(bzs::db::protocol::tdap::client::groupFuncBase, 1)
68
+ BOOST_CLASS_VERSION(bzs::db::protocol::tdap::client::queryBase, 1)
66
69
 
67
70
  namespace bzs
68
71
  {
@@ -201,7 +204,7 @@ void serialize(Archive& ar, queryBase& q, const unsigned int version)
201
204
  }
202
205
 
203
206
  template <class Archive>
204
- void save(Archive& ar, const queryBase& q, const unsigned int /*version*/)
207
+ void save(Archive& ar, const queryBase& q, const unsigned int version)
205
208
  {
206
209
  std::_tstring s = q.toString();
207
210
 
@@ -214,12 +217,22 @@ void save(Archive& ar, const queryBase& q, const unsigned int /*version*/)
214
217
  ar& make_nvp("optimize", v);
215
218
  v = q.isBookmarkAlso();
216
219
  ar& make_nvp("boolmarkAlso", v);
220
+
221
+ if (version >= 1)
222
+ {
223
+ v = q.getDirection();
224
+ ar& make_nvp("direction", v);
225
+
226
+ v = q.isStopAtLimit();
227
+ ar& make_nvp("stopAtLimit", v);
228
+
229
+ }
217
230
  v = q.isAll();
218
231
  ar& make_nvp("isAll", v);
219
232
  }
220
233
 
221
234
  template <class Archive>
222
- void load(Archive& ar, queryBase& q, const unsigned int /*version*/)
235
+ void load(Archive& ar, queryBase& q, const unsigned int version)
223
236
  {
224
237
  std::_tstring s;
225
238
  int v;
@@ -240,6 +253,13 @@ void load(Archive& ar, queryBase& q, const unsigned int /*version*/)
240
253
  ar& make_nvp("boolmarkAlso", v);
241
254
  q.bookmarkAlso(v != 0);
242
255
 
256
+ if (version >= 1)
257
+ {
258
+ ar& make_nvp("direction", v);
259
+ q.direction((table::eFindType)v);
260
+ ar& make_nvp("stopAtLimit", v);
261
+ q.stopAtLimit(v == 1);
262
+ }
243
263
  ar& make_nvp("isAll", v);
244
264
  if (v)
245
265
  q.all();
@@ -342,6 +362,18 @@ void serialize(Archive& ar, max& q, const unsigned int /*version*/)
342
362
  ar& make_nvp("param", boost::serialization::base_object<groupFuncBase>(q));
343
363
  }
344
364
 
365
+ template <class Archive>
366
+ void serialize(Archive& ar, first& q, const unsigned int /*version*/)
367
+ {
368
+ ar& make_nvp("param", boost::serialization::base_object<groupFuncBase>(q));
369
+ }
370
+
371
+ template <class Archive>
372
+ void serialize(Archive& ar, last& q, const unsigned int /*version*/)
373
+ {
374
+ ar& make_nvp("param", boost::serialization::base_object<groupFuncBase>(q));
375
+ }
376
+
345
377
  template <class Archive>
346
378
  void serialize(Archive& ar, groupQuery& q, const unsigned int /*version*/)
347
379
  {
@@ -449,6 +481,12 @@ groupFuncBase& groupByStatement::addFunction(eFunc v,
449
481
  case fmax:
450
482
  func = new client::max(targetNames, resultName);
451
483
  break;
484
+ case ffirst:
485
+ func = new client::first(targetNames, resultName);
486
+ break;
487
+ case flast:
488
+ func = new client::last(targetNames, resultName);
489
+ break;
452
490
  };
453
491
  m_statements->push_back(func);
454
492
  return *func;
@@ -88,7 +88,9 @@ public:
88
88
  fcount,
89
89
  favg,
90
90
  fmin,
91
- fmax
91
+ fmax,
92
+ ffirst,
93
+ flast
92
94
  };
93
95
  groupByStatement();
94
96
  ~groupByStatement();
@@ -103,7 +105,7 @@ public:
103
105
  static groupByStatement* create();
104
106
  };
105
107
 
106
- #define MAX_FUNCTION_SIZE (int) groupByStatement::fmax + 1
108
+ #define MAX_FUNCTION_SIZE (int) groupByStatement::flast + 1
107
109
 
108
110
  class DLLLIBSTMT matchByStatement : public recordsetQuery, public executable
109
111
  {
@@ -144,6 +144,7 @@ const char* getFieldTypeName(uchar_td fieldType, int size, bool nobinary,
144
144
  if (size == 8)
145
145
  return "DOUBLE";
146
146
  case ft_string:
147
+ case ft_wstring:
147
148
  sprintf_s(g_buf, TMP_BUFSIZE, "BINARY(%d)", size);
148
149
  return g_buf;
149
150
  case ft_zstring:
@@ -418,12 +418,12 @@ public:
418
418
  typedef myVarBinaryStoreBase myWvarBinaryStore;
419
419
  typedef myVarBinaryStoreBase myVarBinaryStore;
420
420
 
421
- class myBinaryStoreBase
421
+ class binaryStoreBase
422
422
  {
423
423
  const fielddef& m_fd;
424
424
 
425
425
  public:
426
- inline myBinaryStoreBase(const fielddef& fd) : m_fd(fd){};
426
+ inline binaryStoreBase(const fielddef& fd) : m_fd(fd){};
427
427
 
428
428
  inline size_t maxStoreBytes() const { return m_fd.len; };
429
429
 
@@ -436,8 +436,8 @@ public:
436
436
  inline bool isNeedReadCopy() const { return true; }
437
437
  };
438
438
 
439
- typedef myBinaryStoreBase myWbinaryStore;
440
- typedef myBinaryStoreBase myBinaryStore;
439
+ typedef binaryStoreBase wbinaryStore;
440
+ typedef binaryStoreBase binaryStore;
441
441
 
442
442
  class zstringStore
443
443
  {