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
@@ -209,13 +209,15 @@ public:
209
209
  m_tb->m_impl->mraPtr->duplicateRow(row + rowOffset, count);
210
210
  }
211
211
 
212
- inline void resetMra(filter* p, uchar_td* data, unsigned int totalSize,
212
+ inline void reset(filter* p, uchar_td* data, unsigned int totalSize,
213
213
  const blobHeader* hd)
214
214
  {
215
- reset(p, data, totalSize, hd);
215
+ doReset(p, data, totalSize, hd);
216
+ multiRecordAlocator* mra = m_tb->m_impl->mraPtr;
217
+ if (!mra) return;
216
218
  if (m_rowCount)
217
219
  {
218
- multiRecordAlocator* mra = m_tb->m_impl->mraPtr;
220
+
219
221
  unsigned char* bd = NULL; //blob data
220
222
  if (m_filter->hasManyJoin())
221
223
  hasManyJoinMra(m_rowCount, data);
@@ -258,18 +260,22 @@ public:
258
260
  resultOffset += fd.len;
259
261
  }
260
262
  }
261
- else if (m_tb->valiableFormatType())
262
- {
263
- memset(m_tmpPtr, 0, td->maxRecordLen);
264
- memcpy(m_tmpPtr, m_ptr, m_len);
265
- m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
266
- m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
267
- resultOffset = m_unpackLen;
268
- }
269
263
  else
270
264
  {
271
- memcpy(m_tmpPtr, m_ptr, m_len);
272
- resultOffset = m_len;
265
+ if (m_tb->valiableFormatType())
266
+ {
267
+ memset(m_tmpPtr, 0, td->maxRecordLen);
268
+ memcpy(m_tmpPtr, m_ptr, m_len);
269
+ m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
270
+ resultOffset = m_unpackLen;
271
+ }
272
+ else
273
+ {
274
+ memcpy(m_tmpPtr, m_ptr, m_len);
275
+ resultOffset = m_len;
276
+ }
277
+ if (bd)
278
+ bd = m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd, bd);
273
279
  }
274
280
  }
275
281
  ++m_row;
@@ -281,7 +287,7 @@ public:
281
287
  setMemblockType(mra_nextrows);
282
288
  }
283
289
 
284
- inline void reset(filter* p, uchar_td* data, unsigned int totalSize,
290
+ inline void doReset(filter* p, uchar_td* data, unsigned int totalSize,
285
291
  const blobHeader* hd)
286
292
  {
287
293
  m_filter = p;
@@ -434,26 +440,6 @@ uchar_td table::charset() const
434
440
  return (*m_tableDef)->charsetIndex;
435
441
  }
436
442
 
437
- bool table::trimPadChar() const
438
- {
439
- return m_fddefs->trimPadChar;
440
- }
441
-
442
- void table::setTrimPadChar(bool v)
443
- {
444
- m_fddefs->trimPadChar = v;
445
- }
446
-
447
- bool table::usePadChar() const
448
- {
449
- return m_fddefs->usePadChar;
450
- }
451
-
452
- void table::setUsePadChar(bool v)
453
- {
454
- m_fddefs->usePadChar = v;
455
- }
456
-
457
443
  void* table::dataBak() const
458
444
  {
459
445
  return m_impl->dataBak;
@@ -709,18 +695,16 @@ void table::btrvGetExtend(ushort_td op)
709
695
  stat = STATUS_LIMMIT_OF_REJECT;
710
696
 
711
697
  const blobHeader* hd = blobFieldUsed() ? getBlobHeader() : NULL;
712
- if (m_impl->mraPtr)
713
- {
714
- m_impl->rc->resetMra(filter, (uchar_td*)m_pdata, m_datalen, hd);
715
- m_stat = stat;
716
- m_impl->filterPtr->setStat(stat);
717
- }
718
- else
698
+
699
+ // When using MRA,the read data is then copied all to recordset.
700
+ m_impl->rc->reset(filter, (uchar_td*)m_pdata, m_datalen, hd);
701
+
702
+ m_stat = stat;
703
+ m_impl->filterPtr->setStat(stat);
704
+
705
+ if (!m_impl->mraPtr)
719
706
  {
720
- m_impl->rc->reset(filter, (uchar_td*)m_pdata, m_datalen, hd);
721
- m_stat = stat;
722
- m_impl->filterPtr->setStat(stat);
723
- // There is the right record.
707
+ // When read one or more record(s), then stat set to 0.
724
708
  if (m_impl->rc->rowCount() && (!m_impl->exBookMarking))
725
709
  {
726
710
  m_pdata = (void*)m_impl->rc->setRow(0);
@@ -733,24 +717,47 @@ void table::btrvGetExtend(ushort_td op)
733
717
 
734
718
  }
735
719
 
736
- bool table::recordsLoop(ushort_td& op)
720
+ /*
721
+ Reading continued control
722
+
723
+ When MRA enabled and reject=0 and m_stat = STATUS_LIMMIT_OF_REJECT,
724
+ continuing find operation automaticaly.
725
+ And when MRA enabled stat=0 too, continuing find operation automaticaly.
726
+
727
+ When MRA not enabled, only reject=0 and m_stat = STATUS_LIMMIT_OF_REJECT
728
+ continuing find operation automaticaly. When stat=0, not continue.
729
+
730
+ */
731
+
732
+ bool table::isReadContinue(ushort_td& op)
737
733
  {
738
734
  client::filter* filter = m_impl->filterPtr.get();
739
735
  filter->setPosTypeNext(true);
740
- bool flag = (m_stat == STATUS_LIMMIT_OF_REJECT && (filter->rejectCount() == 0));
741
- if (m_impl->mraPtr && !flag)
742
- {
743
- flag = m_impl->filterPtr->isStatContinue();
744
- if (!flag)
745
- m_stat = m_impl->filterPtr->translateStat();//finish
746
- }
747
- if (flag)
736
+
737
+ //reject count control
738
+ bool isContinue = (m_stat == STATUS_LIMMIT_OF_REJECT &&
739
+ (filter->rejectCount() == 0));
740
+ if (m_impl->mraPtr && !isContinue)
741
+ isContinue = filter->isStatContinue();
742
+
743
+ // limit count control
744
+ if (isContinue)
748
745
  {
749
- op = m_impl->filterPtr->isSeeksMode() ?
750
- TD_KEY_SEEK_MULTI : (m_impl->filterPtr->direction() == table::findForword) ?
746
+ if (filter->isStopAtLimit() && m_impl->rc->rowCount() == filter->maxRows())
747
+ {
748
+ m_stat = STATUS_LIMMIT_OF_REJECT;
749
+ return false;
750
+ }
751
+
752
+ // set next operation type and status
753
+ op = filter->isSeeksMode() ?
754
+ TD_KEY_SEEK_MULTI : (filter->direction() == table::findForword) ?
751
755
  TD_KEY_NEXT_MULTI : TD_KEY_PREV_MULTI;
756
+ return true;
752
757
  }
753
- return flag;
758
+ if (m_impl->mraPtr)
759
+ m_stat = filter->translateStat();
760
+ return false;
754
761
  }
755
762
 
756
763
  void table::getRecords(ushort_td op)
@@ -758,13 +765,20 @@ void table::getRecords(ushort_td op)
758
765
  do
759
766
  {
760
767
  btrvGetExtend(op);
761
- }while (recordsLoop(op));
768
+ }while (isReadContinue(op));
762
769
 
763
770
  if ((m_stat == STATUS_REACHED_FILTER_COND) ||
764
771
  (m_stat == STATUS_LIMMIT_OF_REJECT))
765
772
  m_stat = STATUS_EOF;
766
773
  }
767
774
 
775
+ short table::statReasonOfFind() const
776
+ {
777
+ if (m_impl->filterPtr)
778
+ return m_impl->filterPtr->stat();
779
+ return stat();
780
+ }
781
+
768
782
  bookmark_td table::bookmarkFindCurrent() const
769
783
  {
770
784
 
@@ -870,6 +884,13 @@ void table::btrvSeekMulti()
870
884
  m_stat = STATUS_EOF;
871
885
  }
872
886
 
887
+ nstable::eFindType table::lastFindDirection() const
888
+ {
889
+ if (m_impl->filterPtr)
890
+ return m_impl->filterPtr->direction();
891
+ return findForword;
892
+ }
893
+
873
894
  void table::doFind(ushort_td op, bool notIncCurrent)
874
895
  {
875
896
  /*
@@ -963,9 +984,15 @@ void table::find(eFindType type)
963
984
  m_stat = STATUS_FILTERSTRING_ERROR;
964
985
  return;
965
986
  }
987
+ bool isContinue = (type == findContinue);
966
988
  ushort_td op;
967
-
968
- if (m_impl->filterPtr->isSeeksMode())
989
+ if (isContinue)
990
+ {
991
+ type = m_impl->filterPtr->direction();
992
+ op =(type == findForword) ? TD_KEY_NEXT_MULTI : TD_KEY_PREV_MULTI;
993
+ m_stat = 0;
994
+ }
995
+ else if (m_impl->filterPtr->isSeeksMode())
969
996
  {
970
997
  m_impl->filterPtr->resetSeeksWrited();
971
998
  op = TD_KEY_SEEK_MULTI;
@@ -974,11 +1001,9 @@ void table::find(eFindType type)
974
1001
  op =
975
1002
  (type == findForword) ? TD_KEY_GE_NEXT_MULTI : TD_KEY_LE_PREV_MULTI;
976
1003
 
1004
+ m_impl->rc->reset();
977
1005
  if (isUseTransactd())
978
- {
979
- m_impl->rc->reset();
980
1006
  doFind(op, true /*notIncCurrent*/);
981
- }
982
1007
  else
983
1008
  {
984
1009
  if (op == TD_KEY_SEEK_MULTI)
@@ -991,10 +1016,13 @@ void table::find(eFindType type)
991
1016
  // TD_KEY_SEEK_MULTI
992
1017
  return;
993
1018
  }
994
- if (type == findForword)
995
- seekGreater(true);
996
- else
997
- seekLessThan(true);
1019
+ if (!isContinue)
1020
+ {
1021
+ if (type == findForword)
1022
+ seekGreater(true);
1023
+ else if (type == findBackForword)
1024
+ seekLessThan(true);
1025
+ }
998
1026
  if (m_stat == 0)
999
1027
  {
1000
1028
  if (type == findForword)
@@ -1556,7 +1584,7 @@ const blobHeader* table::getBlobHeader()
1556
1584
  return p;
1557
1585
  }
1558
1586
 
1559
- void table::setBlobFieldPointer(char* ptr, const blobHeader* hd)
1587
+ unsigned char* table::setBlobFieldPointer(char* ptr, const blobHeader* hd, unsigned char* to)
1560
1588
  {
1561
1589
  if (hd)
1562
1590
  {
@@ -1567,14 +1595,25 @@ void table::setBlobFieldPointer(char* ptr, const blobHeader* hd)
1567
1595
  fielddef& fd = (*m_tableDef)->fieldDefs[f->fieldNum];
1568
1596
  char* fdptr = ptr + fd.pos;
1569
1597
  int sizeByte = fd.blobLenBytes();
1598
+
1599
+ //copy size byte
1570
1600
  memcpy(fdptr, &f->size, sizeByte);
1571
1601
  const char* data = f->data();
1602
+ //copy data
1603
+ if (to)
1604
+ {
1605
+ memcpy(to, data, f->size);
1606
+ data = (char*)to;
1607
+ to += f->size;
1608
+ }
1609
+ //copy address
1572
1610
  memcpy(fdptr + sizeByte, &data, sizeof(char*));
1573
1611
  f = f->next();
1574
1612
  }
1575
1613
  ++hd->curRow;
1576
1614
  hd->nextField = (blobField*)f;
1577
1615
  }
1616
+ return to;
1578
1617
  }
1579
1618
 
1580
1619
  void table::onReadAfter()
@@ -2081,7 +2120,7 @@ struct impl
2081
2120
  impl()
2082
2121
  : m_reject(1), m_limit(0), m_joinKeySize(0),
2083
2122
  m_optimize(queryBase::none), m_direction(table::findForword),
2084
- m_nofilter(false), m_withBookmark(false)
2123
+ m_nofilter(false), m_withBookmark(false), m_stopAtLimit(false)
2085
2124
  {
2086
2125
  }
2087
2126
 
@@ -2096,7 +2135,11 @@ struct impl
2096
2135
  queryBase::eOptimize m_optimize;
2097
2136
  table::eFindType m_direction;
2098
2137
  bool m_nofilter;
2099
- bool m_withBookmark;
2138
+ struct
2139
+ {
2140
+ bool m_withBookmark : 1;
2141
+ bool m_stopAtLimit : 1;
2142
+ };
2100
2143
  };
2101
2144
 
2102
2145
  queryBase::queryBase() : m_impl(new impl)
@@ -2179,7 +2222,6 @@ void queryBase::addSeekKeyValue(const _TCHAR* value, bool reset)
2179
2222
  m_impl->m_keyValuesPtr.clear();
2180
2223
  }
2181
2224
  m_impl->m_keyValues.push_back(value);
2182
- // m_impl->m_reject = 1;
2183
2225
  m_impl->m_nofilter = false;
2184
2226
  }
2185
2227
 
@@ -2386,6 +2428,17 @@ bool queryBase::isAll() const
2386
2428
  return m_impl->m_nofilter;
2387
2429
  }
2388
2430
 
2431
+ bool queryBase::isStopAtLimit() const
2432
+ {
2433
+ return m_impl->m_stopAtLimit;
2434
+ }
2435
+
2436
+ queryBase& queryBase::stopAtLimit(bool v)
2437
+ {
2438
+ m_impl->m_stopAtLimit = v;
2439
+ return *this;
2440
+ }
2441
+
2389
2442
  const std::vector<std::_tstring>& queryBase::getSelects() const
2390
2443
  {
2391
2444
  return m_impl->m_selects;
@@ -93,7 +93,8 @@ class DLLLIB table : public nstable
93
93
  bool checkIndex(short index) const;
94
94
  void getKeySpec(keySpec* ks, bool SpecifyKeyNum = false);
95
95
  const bzs::db::blobHeader* getBlobHeader();
96
- void setBlobFieldPointer(char* ptr, const ::bzs::db::blobHeader* p);
96
+ unsigned char* setBlobFieldPointer(char* ptr, const ::bzs::db::blobHeader* p,
97
+ unsigned char* to=NULL);
97
98
  void addSendBlob(const bzs::db::blob* blob);
98
99
  void addBlobEndRow();
99
100
  void resetSendBlob();
@@ -111,7 +112,8 @@ class DLLLIB table : public nstable
111
112
  void btrvSeekMulti();
112
113
  bool doSeekMultiAfter(int row);
113
114
  void* doDdba(uint_td size);
114
- bool recordsLoop(ushort_td& op);
115
+ bool isReadContinue(ushort_td& op);
116
+
115
117
  protected:
116
118
  explicit table(nsdatabase* pbe); // Inheritance is impossible
117
119
  virtual ~table();
@@ -167,10 +169,6 @@ public:
167
169
 
168
170
  bool logicalToString() const;
169
171
  void setLogicalToString(bool v);
170
- bool trimPadChar() const;
171
- void setTrimPadChar(bool v);
172
- bool usePadChar() const;
173
- void setUsePadChar(bool v);
174
172
  void* optionalData() const;
175
173
  void setOptionalData(void* v);
176
174
  bool myDateTimeValueByBtrv() const;
@@ -188,6 +186,8 @@ public:
188
186
  void findLast();
189
187
  void findNext(bool notIncCurrent = true);
190
188
  void findPrev(bool notIncCurrent = true);
189
+ short statReasonOfFind() const ;
190
+ eFindType lastFindDirection() const;
191
191
  bookmark_td bookmarkFindCurrent() const;
192
192
  pq_handle setQuery(const queryBase* query, bool serverPrepare=false);
193
193
  pq_handle prepare(const queryBase* query, bool serverPrepare=false)
@@ -340,7 +340,7 @@ public:
340
340
  queryBase& optimize(eOptimize v);
341
341
  queryBase& bookmarkAlso(bool v);
342
342
  queryBase& joinKeySize(int v);
343
-
343
+ queryBase& stopAtLimit(bool v);
344
344
  const _TCHAR* toString() const;
345
345
  table::eFindType getDirection() const;
346
346
  int getReject() const;
@@ -348,6 +348,7 @@ public:
348
348
  bool isAll() const;
349
349
  int getJoinKeySize() const;
350
350
  eOptimize getOptimize() const;
351
+ bool isStopAtLimit() const;
351
352
  bool isBookmarkAlso() const;
352
353
  short selectCount() const;
353
354
  const _TCHAR* getSelect(short index) const;
@@ -495,6 +495,25 @@ public:
495
495
  {
496
496
  return q.getDirection();
497
497
  }
498
+
499
+ template <class Any_Map_type>
500
+ activeObject& readMapMore(Any_Map_type& map)
501
+ {
502
+ mraResetter mras(m_tb);
503
+ map.init(m_option, m_fdi, m_map, m_tb, &m_alias);
504
+ m_tb->find(table::findContinue);
505
+ if (m_tb->lastFindDirection() == table::findForword)
506
+ {
507
+ findIterator itsf(*m_tb);
508
+ for_each(itsf, map);
509
+ }
510
+ else
511
+ {
512
+ findRvIterator itsf(*m_tb);
513
+ for_each(itsf, map);
514
+ }
515
+ return *this;
516
+ }
498
517
 
499
518
  template <class Any_Map_type , class Query>
500
519
  activeObject& readMap(Any_Map_type& map, Query& q)
@@ -520,7 +539,7 @@ public:
520
539
  return *this;
521
540
  }
522
541
 
523
- template <class Any_Map_type, class Query>
542
+ template <class Any_Map_type, class Query>
524
543
  activeObject& readMap(Any_Map_type& map, Query& q, validationFunc func)
525
544
  {
526
545
  mraResetter mras(m_tb);
@@ -553,6 +572,19 @@ public:
553
572
  return readMap(map, q, func);
554
573
  }
555
574
 
575
+ activeObject& readMore(collection_vec_type& mdls)
576
+ {
577
+ mdlsHandler<MAP, collection_vec_type> map(mdls);
578
+ return readMapMore(map);
579
+ }
580
+
581
+ template <class Container>
582
+ activeObject& readMore(Container& mdls)
583
+ {
584
+ typename MAP::collection_orm_typename map(mdls);
585
+ return readMapMore(map);
586
+ }
587
+
556
588
  template <class Query>
557
589
  activeObject& read(collection_vec_type& mdls, Query& q)
558
590
  {
@@ -93,7 +93,7 @@ inline int compareWvartype(const char* l, const char* r, bool bin, char logType)
93
93
  tmp);
94
94
  else if (bin)
95
95
  tmp =
96
- memcmp((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)), tmp);
96
+ wmemcmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)), tmp);
97
97
  else
98
98
  tmp = wcsncmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)),
99
99
  tmp);
@@ -194,6 +194,8 @@ short schemaBuilder::insertMetaRecord(table* mtb, table* src, int id)
194
194
  fd.type = convFieldType(src->fieldRealType(i), src->fieldFlags(i),
195
195
  isBinary(src->fieldCharset(i)),
196
196
  isUnicode(src->fieldCharset(i)));
197
+ bool usePadChar = ((fd.type == ft_mychar) || (fd.type == ft_mywchar));
198
+ fd.setPadCharSettings(usePadChar, true);
197
199
  fd.setCharsetIndex(charsetIndex(src->fieldCharset(i).csname));
198
200
  pos += fd.len;
199
201
  datalen =
@@ -230,7 +232,7 @@ short schemaBuilder::insertMetaRecord(table* mtb, table* src, int id)
230
232
  isBinary(src->fieldCharset(i)),
231
233
  isUnicode(src->fieldCharset(sg.fieldNum)))))
232
234
  sg.flags.bitA =
233
- !(src->fieldFlags(sg.fieldNum) & BINCMP_FLAG);
235
+ !(src->fieldFlags(sg.fieldNum) & BINARY_FLAG);// case in-sencitive
234
236
  if (src->fieldDataLen(sg.fieldNum) != ks.length)
235
237
  {
236
238
  fielddef& fd = tdef.fieldDefs[sg.fieldNum];
@@ -206,7 +206,7 @@ inline int compareWvartype(const char* l, const char* r, bool bin, char logType)
206
206
  tmp);
207
207
  else if (bin)
208
208
  tmp =
209
- memcmp((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)), tmp);
209
+ wmemcmp16((const char16_t*)(l + sizeof(T)), (const char16_t*)(r + sizeof(T)), tmp);
210
210
  else
211
211
  tmp = wcsncmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)),
212
212
  tmp);
@@ -365,10 +365,10 @@ public:
365
365
  case ft_wstring:
366
366
  case ft_wzstring:
367
367
  if (logType & CMPLOGICAL_CASEINSENSITIVE)
368
- return wcsnicmp16((char16_t*)l, (char16_t*)r, len);
368
+ return wcsnicmp16((char16_t*)l, (char16_t*)r, len/sizeof(char16_t));
369
369
  if ((type == ft_wstring) || (type == ft_mywchar))
370
370
  return memcmp(l, r, len);
371
- return wcsncmp16((char16_t*)l, (char16_t*)r, len);
371
+ return wcsncmp16((char16_t*)l, (char16_t*)r, len/sizeof(char16_t));
372
372
  case ft_lstring:
373
373
  case ft_myvarchar:
374
374
  case ft_myvarbinary:
@@ -633,6 +633,16 @@ class fieldAdapter
633
633
  mutable bool m_judge : 1;
634
634
  mutable bool m_matched : 1;
635
635
  };
636
+ #ifdef COMP_USE_FUNCTION_POINTER
637
+ void setWstringCompLen()
638
+ {
639
+ if ((m_compFunc == &logicalField::compiWString) ||
640
+ (m_compFunc == &logicalField::compWString))
641
+ const_cast<logicalField*>(m_fd)->len /= sizeof(char16_t);
642
+ }
643
+ #else
644
+ void setWstringCompLen(){};
645
+ #endif
636
646
  public:
637
647
  friend class fields;
638
648
 
@@ -659,6 +669,7 @@ public:
659
669
  const_cast<logicalField*>(fd)->opr &= ~FILTER_COMBINE_PREPARE;
660
670
  #ifdef COMP_USE_FUNCTION_POINTER
661
671
  m_compFunc = fd->getCompFunc(m_sizeBytes);
672
+ setWstringCompLen();
662
673
  #endif
663
674
  if (fd->opr == 2)
664
675
  {
@@ -678,7 +689,11 @@ public:
678
689
  bool gt = (comp == eGreater) || (comp == eGreaterEq);
679
690
  bool le = (comp == eLess) || (comp == eLessEq);
680
691
  bool valid = !(forword ? gt : le);
681
- if (valid)
692
+
693
+ // case in-sencitive, Index judge need clinet and server are same option.
694
+ bool is_cl = ((fd->logType & CMPLOGICAL_CASEINSENSITIVE) != 0);
695
+ bool is_srv = ((key->key_part[segmentIndex].field->flags & BINARY_FLAG) == 0);
696
+ if (valid && (is_cl == is_srv))
682
697
  {
683
698
  m_keySeg = (unsigned char)segmentIndex + 1;
684
699
  m_judgeType = (comp == eEqual) ? 2 : 1;
@@ -695,6 +710,7 @@ public:
695
710
  {
696
711
  const_cast<logicalField*>(p)->opr = opr;
697
712
  m_fd = p;
713
+ setWstringCompLen();
698
714
  }
699
715
 
700
716
  inline int checkNomore(bool typeNext, eCompType log) const
@@ -88,6 +88,13 @@ public:
88
88
 
89
89
  p += sizeof(unsigned int); // space of totalLen
90
90
 
91
+ //add posblk bookmark
92
+ if ((P_MASK_POSBLK & paramMask) && tb->cursor())
93
+ {
94
+ paramMask |= P_MASK_PB_BOOKMARK;
95
+ if (tb->isDelayAutoCommit())
96
+ paramMask |= P_MASK_PB_LOCKED;
97
+ }
91
98
  memcpy(p, (const char*)(&paramMask), sizeof(ushort_td));
92
99
  p += sizeof(ushort_td);
93
100
 
@@ -99,6 +106,13 @@ public:
99
106
  {
100
107
  memcpy(p, (const char*)pbk, TD_POSBLK_TRANSMIT_SIZE);
101
108
  p += TD_POSBLK_TRANSMIT_SIZE;
109
+ if (P_MASK_PB_BOOKMARK & paramMask)
110
+ {
111
+ uint v = tb->posPtrLenRaw();
112
+ memcpy(p++, &v, 1);
113
+ memcpy(p, tb->position(true), v);
114
+ p += v;
115
+ }
102
116
  }
103
117
 
104
118
  if (P_MASK_DATALEN & paramMask)