transactd 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/{BUILD_UNIX-JA → BUILD_UNIX-JA.md} +6 -6
  3. data/CMakeLists.txt +20 -15
  4. data/{README-JA → README-JA.md} +23 -23
  5. data/{README → README.md} +22 -24
  6. data/RELEASE_NOTE +120 -0
  7. data/RELEASE_NOTE-JA +110 -0
  8. data/bin/common/tdclc_32_2_4.dll +0 -0
  9. data/bin/common/tdclc_64_2_4.dll +0 -0
  10. data/build/common/get_ruby_path.cmake +1 -1
  11. data/build/swig/ruby/tdclrb_wrap.cpp +1319 -830
  12. data/build/swig/tdcl.i +22 -2
  13. data/build/tdclc/tdclc.cbproj +1 -1
  14. data/build/tdclc/tdclc.rc +4 -4
  15. data/build/tdclcpp/tdclcpp.rc +4 -4
  16. data/build/tdclcpp/tdclcpp_bc.cbproj +2 -1
  17. data/build/tdclrb/CMakeLists.txt +6 -1
  18. data/build/tdclrb/bldgem/extconf.rb +5 -1
  19. data/build/tdclrb/tdclrb.rc +4 -4
  20. data/source/bzs/db/engine/mysql/database.cpp +44 -40
  21. data/source/bzs/db/engine/mysql/database.h +28 -8
  22. data/source/bzs/db/engine/mysql/dbManager.cpp +2 -0
  23. data/source/bzs/db/engine/mysql/dbManager.h +2 -7
  24. data/source/bzs/db/engine/mysql/mysqlInternal.h +79 -7
  25. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +5 -1
  26. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +32 -8
  27. data/source/bzs/db/protocol/tdap/client/activeTable.h +17 -4
  28. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
  29. data/source/bzs/db/protocol/tdap/client/client.cpp +51 -6
  30. data/source/bzs/db/protocol/tdap/client/client.h +41 -11
  31. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +51 -15
  32. data/source/bzs/db/protocol/tdap/client/connMgr.h +6 -1
  33. data/source/bzs/db/protocol/tdap/client/database.cpp +26 -5
  34. data/source/bzs/db/protocol/tdap/client/database.h +3 -2
  35. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +38 -28
  36. data/source/bzs/db/protocol/tdap/client/dbDef.h +1 -1
  37. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +2 -32
  38. data/source/bzs/db/protocol/tdap/client/field.cpp +0 -1
  39. data/source/bzs/db/protocol/tdap/client/filter.h +60 -33
  40. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +2 -5
  41. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +9 -0
  42. data/source/bzs/db/protocol/tdap/client/memRecord.h +1 -0
  43. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +99 -48
  44. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +5 -2
  45. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +76 -26
  46. data/source/bzs/db/protocol/tdap/client/nsTable.h +6 -4
  47. data/source/bzs/db/protocol/tdap/client/request.h +28 -11
  48. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +19 -11
  49. data/source/bzs/db/protocol/tdap/client/table.cpp +157 -70
  50. data/source/bzs/db/protocol/tdap/client/table.h +20 -5
  51. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +57 -4
  52. data/source/bzs/db/protocol/tdap/client/trdormapi.h +55 -20
  53. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +65 -31
  54. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +2 -0
  55. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +24 -36
  56. data/source/bzs/db/protocol/tdap/mysql/request.h +1 -1
  57. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +98 -18
  58. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +12 -7
  59. data/source/bzs/db/protocol/tdap/tdapRequest.h +3 -8
  60. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +1 -9
  61. data/source/bzs/db/protocol/tdap/tdapSchema.h +31 -1
  62. data/source/bzs/db/protocol/tdap/tdapcapi.h +49 -6
  63. data/source/bzs/db/protocol/tdap/uri.h +41 -6
  64. data/source/bzs/db/transactd/appModule.cpp +0 -1
  65. data/source/bzs/db/transactd/appModule.h +0 -2
  66. data/source/bzs/db/transactd/connManager.cpp +202 -33
  67. data/source/bzs/db/transactd/connManager.h +11 -4
  68. data/source/bzs/db/transactd/connectionRecord.h +19 -5
  69. data/source/bzs/db/transactd/transactd.cpp +39 -8
  70. data/source/bzs/env/crosscompile.cpp +1 -1
  71. data/source/bzs/example/queryData.cpp +1 -1
  72. data/source/bzs/netsvc/client/iconnection.h +2 -0
  73. data/source/bzs/netsvc/client/tcpClient.cpp +48 -26
  74. data/source/bzs/netsvc/client/tcpClient.h +171 -106
  75. data/source/bzs/netsvc/server/IAppModule.h +0 -1
  76. data/source/bzs/netsvc/server/serverPipe.cpp +5 -1
  77. data/source/bzs/netsvc/server/serverPipe.h +2 -1
  78. data/source/bzs/test/tdclatl/test_query_atl.js +105 -0
  79. data/source/bzs/test/tdclphp/transactd_Test.php +129 -11
  80. data/source/bzs/test/tdclrb/transactd_spec.rb +74 -2
  81. data/source/bzs/test/transactdBench/scaling_bench.cpp +1 -1
  82. data/source/bzs/test/trdclengn/test_trdclengn.cpp +45 -20
  83. data/source/global/tdclatl/Bookmark.cpp +28 -0
  84. data/source/global/tdclatl/Bookmark.h +65 -0
  85. data/source/global/tdclatl/Database.cpp +2 -2
  86. data/source/global/tdclatl/Database.h +1 -3
  87. data/source/global/tdclatl/DbDef.cpp +6 -0
  88. data/source/global/tdclatl/DbDef.h +1 -0
  89. data/source/global/tdclatl/QueryBase.cpp +29 -0
  90. data/source/global/tdclatl/QueryBase.h +4 -0
  91. data/source/global/tdclatl/Record.cpp +14 -2
  92. data/source/global/tdclatl/Record.h +1 -1
  93. data/source/global/tdclatl/Table.cpp +80 -16
  94. data/source/global/tdclatl/Table.h +23 -8
  95. data/source/global/tdclatl/_IDatabaseEvents_CP.h +39 -0
  96. data/source/global/tdclatl/activeTable.cpp +2 -2
  97. data/source/global/tdclatl/activeTable.h +1 -1
  98. data/source/global/tdclatl/tdclatl.idl +64 -14
  99. metadata +12 -12
  100. data/bin/common/tdclc_32_2_3.dll +0 -0
  101. data/bin/common/tdclc_64_2_3.dll +0 -0
  102. data/build/tdclcpp/BUILDNUMBER.txt +0 -1
  103. data/build/tdclrb/BUILDNUMBER.txt +0 -1
  104. /data/{BUILD_WIN-JA → BUILD_WIN-JA.md} +0 -0
  105. /data/{README_ORMSRCGEN-JA → README_ORMSRCGEN-JA.md} +0 -0
  106. /data/{README_ORMSRCGEN → README_ORMSRCGEN.md} +0 -0
@@ -426,14 +426,26 @@ void database::doClose()
426
426
  m_impl->lockReadOnly = false;
427
427
  }
428
428
 
429
- void database::close()
429
+ void database::close(bool withDropDefaultSchema)
430
430
  {
431
431
  bool flag = (m_impl->dbDef != NULL);
432
+ if (m_impl && m_impl->dbDef)
433
+ m_impl->dbDef->setKeyNum(withDropDefaultSchema ? CR_SUBOP_DROP : 0);
432
434
  doClose();
433
435
  if (flag)
434
436
  nsdatabase::release();
435
437
  }
436
438
 
439
+ bool database::doReopenDatabaseSchema()
440
+ {
441
+ if (m_impl->dbDef && m_impl->dbDef->isOpen())
442
+ {
443
+ doReconnect(m_impl->dbDef);
444
+ return (m_stat == 0);
445
+ }
446
+ return true;
447
+ }
448
+
437
449
  _TCHAR* database::getTableUri(_TCHAR* buf, short FileNum)
438
450
  {
439
451
  m_stat = STATUS_SUCCESS;
@@ -569,6 +581,12 @@ table* database::openTable(short FileNum, short mode, bool AutoCreate,
569
581
 
570
582
  bool database::createTable(short FileNum, const _TCHAR* FilePath)
571
583
  {
584
+ tabledef* td = m_impl->dbDef->tableDefs(FileNum);
585
+ if (!td || td->fieldCount == 0)
586
+ {
587
+ m_stat = STATUS_INVALID_FIELD_OFFSET;
588
+ return false;
589
+ }
572
590
  if (isTransactdUri(FilePath))
573
591
  {
574
592
  if (setUseTransactd() == false)
@@ -580,7 +598,7 @@ bool database::createTable(short FileNum, const _TCHAR* FilePath)
580
598
  const char* p = toServerUri(buf2, MAX_PATH, FilePath, isUseTransactd());
581
599
 
582
600
  m_stat = m_btrcallid(
583
- TD_CREATETABLE, posblk, m_impl->dbDef->tableDefs(FileNum),
601
+ TD_CREATETABLE, posblk, td,
584
602
  &m_impl->dbDef->m_datalen, (void*)p, (uchar_td)strlen(p),
585
603
  CR_SUBOP_BY_TABLEDEF /* exists check */, clientID());
586
604
  }
@@ -597,7 +615,7 @@ bool database::createTable(short FileNum, const _TCHAR* FilePath)
597
615
  if (FilePath)
598
616
  buf = FilePath;
599
617
  else
600
- buf = m_impl->dbDef->tableDefs(FileNum)->fileName();
618
+ buf = td->fileName();
601
619
  nsdatabase::createTable(fs, 1024, buf, CR_SUBOP_BY_FILESPEC);
602
620
  free(fs);
603
621
  }
@@ -734,11 +752,13 @@ inline void copyEachFieldData(table* dest, table* src, filedChnageInfo* fci)
734
752
  inline int moveVaileRecord(table* src)
735
753
  {
736
754
  int count = 0;
737
- bookmark_td bm = 0;
755
+ bookmark_td bm;
738
756
  src->stepLast();
739
757
  while (src->stat() == STATUS_SUCCESS)
740
758
  {
741
759
  bm = src->bookmark();
760
+ if (src->stat() != STATUS_SUCCESS)
761
+ break;
742
762
  ++count;
743
763
  src->stepPrev();
744
764
  }
@@ -779,6 +799,7 @@ short database::copyTableData(table* dest, table* src, bool turbo, int offset,
779
799
  short keyNum, int maxSkip)
780
800
  {
781
801
  src->setKeyNum((char_td)keyNum);
802
+ dest->setKeyNum(-1);
782
803
  const tabledef* ddef = dest->tableDef();
783
804
  const tabledef* sdef = src->tableDef();
784
805
  ushort_td ins_rows = 0;
@@ -839,7 +860,7 @@ short database::copyTableData(table* dest, table* src, bool turbo, int offset,
839
860
  dest->tdap(TD_REC_INSERT);
840
861
  }
841
862
  else
842
- ins_rows += dest->insert();
863
+ ins_rows += dest->insert(true);
843
864
  if (dest->stat() == STATUS_INVALID_VALLEN)
844
865
  skipCount++;
845
866
  else if (dest->stat() == STATUS_DUPPLICATE_KEYVALUE)
@@ -35,7 +35,7 @@ class database;
35
35
  class table;
36
36
  class dbdef;
37
37
 
38
- #if (defined(__BORLANDC__) && !defined(__clang__))
38
+ #if (defined(__BORLANDC__) && !defined(__APPLE__) && !defined(__clang__))
39
39
  typedef bool __stdcall (*deleteRecordFn)(database* db, table* tb, bool inkey);
40
40
  typedef short __stdcall (*schemaMgrFn)(database* db);
41
41
  typedef void __stdcall (*copyDataFn)(database* db, int recordCount, int count,
@@ -84,6 +84,7 @@ protected:
84
84
  bool& cancel);
85
85
  virtual void doConvertTable(short tableIndex, bool turbo,
86
86
  const _TCHAR* ownerName);
87
+ virtual bool doReopenDatabaseSchema();
87
88
 
88
89
  public:
89
90
  virtual void release();
@@ -111,7 +112,7 @@ public:
111
112
  void create(const _TCHAR* uri, short type = TYPE_SCHEMA_BDF);
112
113
  void drop();
113
114
  void dropTable(const _TCHAR* tableName);
114
- void close();
115
+ void close(bool withDropDefaultSchema = false);
115
116
  short aclReload();
116
117
  short continuous(char_td op = TD_BACKUP_START, bool inclideRepfile = false);
117
118
  short assignSchemaData(dbdef* src);
@@ -42,6 +42,7 @@ namespace client
42
42
  #define FORMAT_VERSON_BTRV_DEF 0
43
43
  #define FORMAT_VERSON_CURRENT 1
44
44
 
45
+ /* BDFFORMAT_VERSION used in the databaseSchema.cpp listSchemaTable() */
45
46
  static const _TCHAR BDFFORMAT_VERSION[] = _T("2.000.00");
46
47
  static const _TCHAR ow0[11] = { 46, 46, 83, 67, 46, 46, 46, 46, 93, 4, 0 };
47
48
  static const _TCHAR ow1[11] = { 46, 46, 83, 67, 46, 46, 46, 46, 66, 5, 0 };
@@ -220,25 +221,23 @@ void dbdef::setCodePage(tabledef* td)
220
221
  }
221
222
  }
222
223
 
223
- void dbdef::updateTableDef(short TableIndex, bool forPsqlDdf)
224
+ short dbdef::validateTableDef(short TableIndex)
224
225
  {
225
226
  m_stat = STATUS_SUCCESS;
226
227
  tabledef* td = tableDefs(TableIndex);
227
- short i, j, ret, Fnum;
228
- uchar_td type;
229
228
 
230
229
  td->optionFlags.bitA = false; // reset valiable type
231
230
  td->optionFlags.bitB = false;
232
- for (i = 0; i < td->fieldCount; ++i)
231
+ for (short i = 0; i < td->fieldCount; ++i)
233
232
  {
234
- ret = fieldNumByName(TableIndex, td->fieldDefs[i].name());
233
+ short ret = fieldNumByName(TableIndex, td->fieldDefs[i].name());
235
234
  if ((ret != -1) && (ret != i))
236
235
  {
237
236
  m_stat = STATUS_DUPLICATE_FIELDNAME;
238
- return;
237
+ return m_stat;
239
238
  }
240
239
  // Check field length.
241
- type = td->fieldDefs[i].type;
240
+ uchar_td type = td->fieldDefs[i].type;
242
241
 
243
242
  // reset update indicator
244
243
  td->fieldDefs[i].enableFlags.bitE = false;
@@ -247,7 +246,7 @@ void dbdef::updateTableDef(short TableIndex, bool forPsqlDdf)
247
246
  if (!ret)
248
247
  {
249
248
  m_stat = STATUS_INVALID_FIELDLENGTH;
250
- return;
249
+ return m_stat;
251
250
  }
252
251
  // Note or Lvar type must be the last of fields.
253
252
  if ((type == ft_note) || (type == ft_lvar))
@@ -255,7 +254,7 @@ void dbdef::updateTableDef(short TableIndex, bool forPsqlDdf)
255
254
  if (i != td->fieldCount - 1)
256
255
  {
257
256
  m_stat = STATUS_LVAR_NOTE_NOT_LAST;
258
- return;
257
+ return m_stat;
259
258
  }
260
259
  }
261
260
 
@@ -265,7 +264,7 @@ void dbdef::updateTableDef(short TableIndex, bool forPsqlDdf)
265
264
  (type != ft_note) && (type != ft_lvar))
266
265
  {
267
266
  m_stat = STATUS_INVALID_VARIABLETABLE;
268
- return;
267
+ return m_stat;
269
268
  }
270
269
  if ((type == ft_myvarchar) || (type == ft_mywvarchar) ||
271
270
  (type == ft_myvarbinary) || (type == ft_mywvarbinary) ||
@@ -276,36 +275,44 @@ void dbdef::updateTableDef(short TableIndex, bool forPsqlDdf)
276
275
  }
277
276
 
278
277
  // Check invalid key type
279
- for (i = 0; i < td->keyCount; i++)
278
+ for (short i = 0; i < td->keyCount; i++)
280
279
  {
281
- for (j = 0; j < td->keyDefs[i].segmentCount; j++)
280
+ for (short j = 0; j < td->keyDefs[i].segmentCount; j++)
282
281
  {
283
- Fnum = td->keyDefs[i].segments[j].fieldNum;
284
- ret = isPassKey(td->fieldDefs[Fnum].type);
282
+ short fnum = td->keyDefs[i].segments[j].fieldNum;
283
+ short ret = isPassKey(td->fieldDefs[fnum].type);
285
284
  if (!ret)
286
285
  {
287
286
  m_stat = STATUS_INVALID_KEYTYPE;
288
- return;
287
+ return m_stat;
289
288
  }
290
289
  }
291
290
  }
292
291
 
293
292
  // Chack duplicate table name.
294
- for (i = 1; i < m_impl->tableCount; i++)
293
+ for (short i = 1; i < m_impl->tableCount; i++)
295
294
  {
296
295
  if ((tableDefs(i)) && (i != TableIndex))
297
296
  {
298
297
  if (strcmp(tableDefs(i)->tableNameA(), td->tableNameA()) == 0)
299
298
  {
300
299
  m_stat = STATUS_DUPPLICATE_KEYVALUE;
301
- return;
300
+ return m_stat;
302
301
  }
303
302
  }
304
303
  }
305
304
  setCodePage(td);
306
-
307
305
  setRecordLen(TableIndex);
308
- td = tableDefs(TableIndex);
306
+ return m_stat;
307
+ }
308
+
309
+ void dbdef::updateTableDef(short TableIndex, bool forPsqlDdf)
310
+ {
311
+ if ((m_stat = validateTableDef(TableIndex)) != 0)
312
+ return;
313
+
314
+ tabledef* td = tableDefs(TableIndex);
315
+
309
316
  if (m_impl->noWriteMode)
310
317
  {
311
318
  m_stat = STATUS_ACCESS_DENIED;
@@ -716,10 +723,9 @@ tabledef* dbdef::tableDefs(int index)
716
723
  }
717
724
  m_datalen =
718
725
  fixVariableLenBug(isUseTransactd(), (tabledef*)m_pdata, m_datalen);
719
-
720
- m_impl->tableDefs[index] = def =
721
- (tabledef*)malloc(getNewVersionSize((tabledef*)m_pdata));
722
-
726
+ size_t size = getNewVersionSize((tabledef*)m_pdata);
727
+ def = (tabledef*)malloc(size);
728
+ m_impl->tableDefs[index] = def;
723
729
  if (def == NULL)
724
730
  {
725
731
  m_stat = STATUS_CANT_ALLOC_MEMORY;
@@ -1709,7 +1715,11 @@ void dbdef::pushBackup(short TableIndex)
1709
1715
  }
1710
1716
 
1711
1717
  setFieldsCharsetIndex(tableDefs(TableIndex));
1712
- memcpy(m_impl->tableDefs[TABLE_NUM_TMP], tableDefs(TableIndex), blen);
1718
+ tabledef* td = m_impl->tableDefs[TABLE_NUM_TMP];
1719
+ memcpy(td, tableDefs(TableIndex), blen);
1720
+ td->fieldDefs = getFieldDef(td);
1721
+ td->keyDefs = getKeyDef(td);
1722
+
1713
1723
  }
1714
1724
 
1715
1725
  bool dbdef::compAsBackup(short TableIndex)
@@ -1745,10 +1755,10 @@ void dbdef::popBackup(short TableIndex)
1745
1755
  int len = totalDefLength(TABLE_NUM_TMP);
1746
1756
  m_impl->tableDefs[TableIndex] =
1747
1757
  (tabledef*)realloc(tableDefs(TableIndex), len);
1748
- memcpy(tableDefs(TableIndex), tableDefs(TABLE_NUM_TMP), len);
1749
- tableDefs(TableIndex)->fieldDefs = getFieldDef(tableDefs(TableIndex));
1750
- tableDefs(TableIndex)->keyDefs = getKeyDef(tableDefs(TableIndex));
1751
-
1758
+ tabledef* td = m_impl->tableDefs[TableIndex];
1759
+ memcpy(td, tableDefs(TABLE_NUM_TMP), len);
1760
+ td->fieldDefs = getFieldDef(td);
1761
+ td->keyDefs = getKeyDef(td);
1752
1762
  updateTableDef(TableIndex);
1753
1763
  }
1754
1764
 
@@ -99,7 +99,7 @@ public:
99
99
  int version() const;
100
100
 
101
101
  inline short_td stat() const { return m_stat; }
102
-
102
+ short validateTableDef(short TableIndex);
103
103
  void updateTableDef(short tableIndex, bool forPsqlDdf = true);
104
104
  fielddef* insertField(short tableIndex, short insertIndex);
105
105
  void deleteField(short tableIndex, short deleteIndex);
@@ -211,13 +211,13 @@ extern "C" PACKAGE_OSX short_td __STDCALL
211
211
  client_t->req().paramMask = P_MASK_NOKEYBUF;
212
212
  break;
213
213
  case TD_UNLOCK:
214
+ case TD_CLOSETABLE:
214
215
  client_t->req().paramMask = P_MASK_POSBLK | P_MASK_KEYNUM;
215
216
  break;
216
217
  case TD_UPDATE_PART:
217
218
  client_t->cleanup();
218
219
  return 0;
219
220
  case TD_REC_DELETE:
220
- case TD_CLOSETABLE:
221
221
  case TD_CLEAR_OWNERNAME:
222
222
  case TD_AUTOMEKE_SCHEMA:
223
223
  client_t->req().paramMask = P_MASK_POSBLK;
@@ -371,37 +371,7 @@ extern "C" PACKAGE_OSX short_td __STDCALL
371
371
  }
372
372
  catch (boost::system::system_error& e)
373
373
  {
374
- switch (e.code().value())
375
- {
376
- case 11004:
377
- case 11001:
378
- ret = ERROR_TD_HOSTNAME_NOT_FOUND;
379
- break;
380
- case 10060:
381
- case 10057: //blocking fire wall
382
- case 110: //connect: Connection timed out
383
- case 121: //timeout sema
384
- case 11: //EAGAIN
385
- ret = ERROR_TD_NET_TIMEOUT;
386
- break;
387
- case 32: //write:brokn pipe
388
- case 111: //connect: Connection refused
389
- case 10061:
390
- ret = ERROR_TD_CONNECTION_FAILURE;
391
- break;
392
- case 104: //write: Connection reset by peer
393
- case 10054:
394
- ret = ERROR_TD_NET_REMOTE_DISCONNECT;
395
- break;
396
- case 232:
397
- case 109:
398
- case 2:
399
- case 1:
400
- ret = ERROR_TD_INVALID_CLINETHOST;
401
- break;
402
- default:
403
- ret = ERROR_TD_NET_OTHER;
404
- }
374
+ ret = errorCode(e.code());
405
375
  OutputDebugString(e.what());
406
376
  char tmp[512];
407
377
  sprintf_s(tmp, 512, "%d %s", e.code().value(), e.what());
@@ -1614,7 +1614,6 @@ void* field::getFVbin(uint_td& size) const
1614
1614
  size = m_fd->len;
1615
1615
  return (void*)(p);
1616
1616
  }
1617
- return NULL;
1618
1617
  }
1619
1618
 
1620
1619
  double field::getFVDecimal() const
@@ -37,7 +37,6 @@ namespace client
37
37
  {
38
38
 
39
39
 
40
- #define BOOKMARK_SIZE 4
41
40
  #define DATASIZE_BYTE 2
42
41
 
43
42
 
@@ -504,12 +503,11 @@ public:
504
503
  }
505
504
  }
506
505
 
507
- int bookmarkSize(bool isTransactd) const
506
+ int bookmarkSize(bool isTransactd, ushort_td bmlen) const
508
507
  {
509
508
  if (isTransactd)
510
- return (itype & FILTER_CURRENT_TYPE_NOBOOKMARK) ? 0 : BOOKMARK_SIZE;
511
- assert(type[0]);
512
- return BOOKMARK_SIZE;
509
+ return (itype & FILTER_CURRENT_TYPE_NOBOOKMARK) ? 0 : bmlen;
510
+ return bmlen;
513
511
  }
514
512
 
515
513
  bool positionTypeNext(bool isTransactd) const
@@ -599,7 +597,7 @@ class filter
599
597
  struct
600
598
  {
601
599
  bool m_stopAtLimit : 1;
602
-
600
+ bool m_seekByBookmarks : 1;
603
601
  };
604
602
 
605
603
  struct bufSize
@@ -740,11 +738,20 @@ class filter
740
738
  {
741
739
  seek& l = m_seeks[index];
742
740
  uchar_td* to = dataBuf;
743
- for (int j = 0; j < joinKeySize; ++j)
741
+ if (m_seekByBookmarks)
744
742
  {
745
- const keyValuePtr& v = keyValues[i + j];
746
- fielddef& fd = fds[kd->segments[j].fieldNum];
747
- to = fd.keyCopy(to, (uchar_td*)v.ptr, v.len);
743
+ const keyValuePtr& v = keyValues[i];
744
+ memcpy(to, (uchar_td*)v.ptr, v.len);
745
+ to += v.len;
746
+ }
747
+ else
748
+ {
749
+ for (int j = 0; j < joinKeySize; ++j)
750
+ {
751
+ const keyValuePtr& v = keyValues[i + j];
752
+ fielddef& fd = fds[kd->segments[j].fieldNum];
753
+ to = fd.keyCopy(to, (uchar_td*)v.ptr, v.len);
754
+ }
748
755
  }
749
756
  if (!l.setParam(dataBuf, (ushort_td)(to - dataBuf)))
750
757
  return false;
@@ -758,25 +765,34 @@ class filter
758
765
  bool prebuiltSeeks( keydef* kd, size_t size, const queryBase* q, int& keySize, uchar_td** dataBuf)
759
766
  {
760
767
  // Check specify key size is smoller than kd->segmentCount or equal
761
- if (keySize == 0)
762
- keySize = kd->segmentCount;
763
- else if (kd->segmentCount < keySize)
764
- return false;
765
- if (size % keySize)
766
- return false;
767
-
768
- m_hasManyJoin = (kd->segmentCount != keySize) || kd->segments[0].flags.bit0;
769
- if (m_hasManyJoin)
770
- m_withBookmark = true;
771
- if (q && m_hasManyJoin &&
772
- !(q->getOptimize() & queryBase::joinHasOneOrHasMany))
773
- return false;
774
- m_seeks.resize(size / keySize);
775
768
  int maxKeylen = 0;
776
- for (int j = 0; j < keySize; ++j)
777
- maxKeylen +=
778
- m_tb->tableDef()->fieldDefs[kd->segments[j].fieldNum].len + 2;
769
+ if (m_seekByBookmarks)
770
+ {
771
+ maxKeylen = m_tb->bookmarkLen();
772
+ m_hasManyJoin = false;
773
+ keySize = 1;
774
+ m_seeks.resize(size);
775
+ }
776
+ else
777
+ {
778
+ if (keySize == 0)
779
+ keySize = kd->segmentCount;
780
+ else if (kd->segmentCount < keySize)
781
+ return false;
782
+ if (size % keySize)
783
+ return false;
779
784
 
785
+ m_hasManyJoin = (kd->segmentCount != keySize) || kd->segments[0].flags.bit0;
786
+ if (m_hasManyJoin)
787
+ m_withBookmark = true;
788
+ if (q && m_hasManyJoin &&
789
+ !(q->getOptimize() & queryBase::joinHasOneOrHasMany))
790
+ return false;
791
+ m_seeks.resize(size / keySize);
792
+ for (int j = 0; j < keySize; ++j)
793
+ maxKeylen +=
794
+ m_tb->tableDef()->fieldDefs[kd->segments[j].fieldNum].len + 2;
795
+ }
780
796
  // alloc databuffer
781
797
  *dataBuf = reallocSeeksDataBuffer(maxKeylen * m_seeks.size());
782
798
  m_hd.rejectCount = 0;
@@ -812,7 +828,7 @@ class filter
812
828
  m_withBookmark = q->isBookmarkAlso();
813
829
  m_cachedOptimize = q->getOptimize();
814
830
  m_stopAtLimit = q->isStopAtLimit();
815
-
831
+ m_seekByBookmarks = q->isSeekByBookmarks();
816
832
 
817
833
  if (q->isAll())
818
834
  addAllFields();
@@ -839,7 +855,7 @@ class filter
839
855
 
840
856
  int resultRowSize(bool ignoreFields) const
841
857
  {
842
- int recordLen = m_hd.bookmarkSize(m_isTransactd) + DATASIZE_BYTE;
858
+ int recordLen = bookmarkSize() + DATASIZE_BYTE;
843
859
  if (!ignoreFields)
844
860
  recordLen += bsize.retRowSize;
845
861
  return recordLen;
@@ -1152,8 +1168,12 @@ public:
1152
1168
  if (!m_withBookmark)
1153
1169
  type |= FILTER_CURRENT_TYPE_NOBOOKMARK;
1154
1170
  if (m_seeksMode)
1171
+ {
1172
+ incCurrent = false;
1155
1173
  type |= FILTER_TYPE_SEEKS;
1156
-
1174
+ if (m_seekByBookmarks)
1175
+ type |= FILTER_TYPE_SEEKS_BOOKMARKS;
1176
+ }
1157
1177
  }
1158
1178
  m_hd.setPositionType(incCurrent, m_isTransactd, type);
1159
1179
  }
@@ -1192,8 +1212,7 @@ public:
1192
1212
 
1193
1213
  ushort_td totalFieldLen() const
1194
1214
  {
1195
- return resultRowSize(false) - m_hd.bookmarkSize(m_isTransactd) -
1196
- DATASIZE_BYTE;
1215
+ return resultRowSize(false) - bookmarkSize() - DATASIZE_BYTE;
1197
1216
  }
1198
1217
 
1199
1218
  ushort_td totalSelectFieldLen() const
@@ -1240,7 +1259,12 @@ public:
1240
1259
 
1241
1260
  inline bool ignoreFields() const { return m_ignoreFields; }
1242
1261
 
1243
- inline int bookmarkSize() const { return m_hd.bookmarkSize(m_isTransactd); }
1262
+ inline int bookmarkSize() const
1263
+ {
1264
+ ushort_td bmlen = (m_seeksMode && m_hasManyJoin) ?
1265
+ 4 : m_tb->bookmarkLen();
1266
+ return m_hd.bookmarkSize(m_isTransactd, bmlen);
1267
+ }
1244
1268
 
1245
1269
  /* The Ignore fields option don't use with multi seek operation.
1246
1270
  because if a server are not found a record then a server return
@@ -1248,6 +1272,7 @@ public:
1248
1272
  */
1249
1273
  inline void setIgnoreFields(bool v) { m_ignoreFields = v; }
1250
1274
  inline bool isSeeksMode() const { return m_seeksMode; }
1275
+ inline bool isSeekByBookmarks() const { return m_seekByBookmarks; }
1251
1276
  inline table::eFindType direction() const { return m_direction; }
1252
1277
  inline bool setDirection(table::eFindType v)
1253
1278
  {
@@ -1304,6 +1329,8 @@ public:
1304
1329
  return setDirection(v ? table::findBackForword : table::findForword);
1305
1330
  }
1306
1331
 
1332
+ bool withBookmark() const { return m_withBookmark; }
1333
+
1307
1334
  static filter* create(table* tb)
1308
1335
  {
1309
1336
  return new filter(tb);
@@ -393,11 +393,8 @@ public:
393
393
  f->init(mdls.fieldDefs());
394
394
 
395
395
  if (f->resultKey() == (int)mdls.fieldDefs()->size())
396
- {
397
- groupFuncBase::numeric_type dummy = 0;
398
396
  mdls.appendField(f->resultName(), f->resultType(),
399
397
  f->resultLen());
400
- }
401
398
  }
402
399
 
403
400
  grouping_comp<recordsetImple> groupingComp(mdls, keyFields);
@@ -584,8 +581,8 @@ public:
584
581
 
585
582
  inline groupFuncBaseImple(const groupFuncBaseImple& r)
586
583
  : m_targetNames(r.m_targetNames), m_resultName(r.m_resultName),
587
- m_resultKey(r.m_resultKey), m_resultType(r.m_resultType),
588
- m_resultLen(r.m_resultLen),
584
+ m_resultKey(r.m_resultKey),
585
+ m_resultLen(r.m_resultLen), m_resultType(r.m_resultType),
589
586
  m_values(r.m_values), m_counts(r.m_counts)
590
587
  {
591
588
  copyStrings(r.m_strings);
@@ -320,6 +320,15 @@ bool writableRecord::read(bool KeysetAlrady)
320
320
  return true;
321
321
  }
322
322
 
323
+ bool writableRecord::read(bookmark_td& bm)
324
+ {
325
+ m_tb->seekByBookmark(bm);
326
+ if (m_tb->stat())
327
+ return false;
328
+ copyFromBuffer(m_tb);
329
+ return true;
330
+ }
331
+
323
332
  void writableRecord::insert()
324
333
  {
325
334
  copyToBuffer(m_tb);
@@ -171,6 +171,7 @@ class DLLLIB writableRecord : public memoryRecord
171
171
  public:
172
172
 
173
173
  bool read(bool KeysetAlrady = false);
174
+ bool read(bookmark_td& bm);
174
175
  void insert();
175
176
  void del(bool KeysetAlrady = false);
176
177
  void update();