transactd 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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)