transactd 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +37 -4
  3. data/bin/common/tdclc_32_1_2.dll +0 -0
  4. data/bin/common/tdclc_64_1_2.dll +0 -0
  5. data/build/common/transactd_cl_common.cmake +0 -1
  6. data/build/common/transactd_common.cmake +26 -6
  7. data/build/swig/php/generate.cmake.in +58 -0
  8. data/build/swig/php/generate.cmd.in +41 -0
  9. data/build/swig/php/php.swg +155 -0
  10. data/build/swig/ruby/ruby.swg +38 -0
  11. data/build/swig/tdcl.i +133 -3
  12. data/build/tdclc/CMakeLists.txt +4 -1
  13. data/build/tdclc/tdclc_32.cbproj +1 -1
  14. data/build/tdclc/tdclc_64.cbproj +1 -1
  15. data/build/tdclcpp/CMakeLists.txt +1 -1
  16. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +1 -4
  17. data/build/tdclcpp/tdclcpp_bcb_64.cbproj +0 -3
  18. data/build/tdclrb/CMakeLists.txt +1 -1
  19. data/build/tdclrb/GEM_VERSION +2 -2
  20. data/source/bzs/db/engine/mysql/IReadRecords.h +1 -1
  21. data/source/bzs/db/engine/mysql/bookmark.h +3 -3
  22. data/source/bzs/db/engine/mysql/database.cpp +95 -19
  23. data/source/bzs/db/engine/mysql/database.h +6 -6
  24. data/source/bzs/db/engine/mysql/mysqlInternal.h +43 -1
  25. data/source/bzs/db/engine/mysql/mysqlThd.cpp +10 -8
  26. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
  27. data/source/bzs/db/protocol/tdap/btrDate.h +2 -2
  28. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +15 -8
  29. data/source/bzs/db/protocol/tdap/client/dbDef.h +2 -2
  30. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +4 -0
  31. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +0 -5
  32. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +0 -4
  33. data/source/bzs/db/protocol/tdap/client/filter.cpp +0 -484
  34. data/source/bzs/db/protocol/tdap/client/filter.h +696 -84
  35. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +13 -3
  36. data/source/bzs/db/protocol/tdap/client/nsTable.h +12 -6
  37. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -1
  38. data/source/bzs/db/protocol/tdap/client/stringConverter.h +1 -0
  39. data/source/bzs/db/protocol/tdap/client/table.cpp +519 -75
  40. data/source/bzs/db/protocol/tdap/client/table.h +49 -7
  41. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +145 -124
  42. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +39 -0
  43. data/source/bzs/db/protocol/tdap/client/trdormapi.h +872 -0
  44. data/source/bzs/db/protocol/tdap/myDateTime.cpp +8 -8
  45. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +7 -9
  46. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +406 -195
  47. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +64 -13
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +2 -1
  49. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +35 -3
  50. data/source/bzs/db/protocol/tdap/tdapSchema.h +11 -3
  51. data/source/bzs/db/protocol/tdap/tdapcapi.h +63 -53
  52. data/source/bzs/env/crosscompile.h +8 -3
  53. data/source/bzs/example/connection_pool_c.cpp +1 -7
  54. data/source/bzs/example/useORM.cpp +585 -0
  55. data/source/bzs/rtl/exception.h +6 -0
  56. data/source/bzs/test/tdclatl/bench_tdclatl.js +12 -7
  57. data/source/bzs/test/tdclphp/transactd_Test.php +1845 -0
  58. data/source/bzs/test/tdclphp/transactd_blob_Test.php +325 -0
  59. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +183 -0
  60. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +212 -0
  61. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +332 -0
  62. data/source/bzs/test/tdclrb/transactd_spec.rb +256 -1
  63. data/source/bzs/test/trdclengn/test_blob.cpp +327 -0
  64. data/source/bzs/test/trdclengn/test_trdclengn.cpp +485 -5
  65. data/source/global/tdclatl/QueryBase.cpp +231 -0
  66. data/source/global/tdclatl/QueryBase.h +96 -0
  67. data/source/global/tdclatl/Table.cpp +24 -0
  68. data/source/global/tdclatl/Table.h +2 -1
  69. data/source/global/tdclatl/resource.h +0 -0
  70. data/source/global/tdclatl/tdclatl.idl +88 -2
  71. metadata +16 -3
  72. data/bin/common/tdclc_32_1_1.dll +0 -0
  73. data/bin/common/tdclc_64_1_1.dll +0 -0
@@ -64,9 +64,6 @@ namespace client
64
64
  #define EXEC_CODEPAGE CP_UTF8
65
65
  #endif
66
66
 
67
- #define BOOKMARK_ALLOC_SIZE 40960
68
- #define BOOKMARK_SIZE 4
69
- #define DATASIZE_BYTE 2
70
67
 
71
68
  class CFiledNameIndex
72
69
  {
@@ -162,6 +159,7 @@ class recordCache
162
159
  char* m_ptr;
163
160
  char* m_tmpPtr;
164
161
  blobHeader* m_hd;
162
+ short_td m_seekMultiStat;
165
163
 
166
164
  public:
167
165
  inline recordCache(table* tb) : m_tb(tb) {reset();}
@@ -199,18 +197,34 @@ public:
199
197
  m_ptr += DATASIZE_BYTE;
200
198
  m_bookmark = *((bookmark_td*)(m_ptr));
201
199
  m_ptr += BOOKMARK_SIZE;
202
-
203
- if (m_hd)
200
+ }
201
+ if (m_hd)
202
+ {
203
+ //blob pointer is allready point to next row
204
+ while (m_row - m_hd->curRow)
204
205
  {
205
- m_hd->nextField = (blobField*)m_hd->nextField->next();
206
+ for(int j=0;j<m_hd->fieldCount;++j)
207
+ m_hd->nextField = (blobField*)m_hd->nextField->next();
206
208
  ++m_hd->curRow;
207
209
  }
208
210
  }
211
+
209
212
  m_tb->m_impl->strBufs.clear();
213
+
214
+ if ((m_len==0) && m_pFilter->isSeeksMode() && m_pFilter->fieldCount())
215
+ {
216
+ /*seek error*/
217
+ m_seekMultiStat = m_bookmark;
218
+ m_bookmark = 0;
219
+ memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
220
+ return m_tmpPtr;
221
+ }else
222
+ m_seekMultiStat = 0;
223
+
210
224
  if (m_pFilter->fieldSelected())
211
225
  {
212
226
  int offset = 0;
213
- memset(m_tmpPtr, 0, m_len);
227
+ memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
214
228
  for (int i = 0; i < m_pFilter->fieldCount(); i++)
215
229
  {
216
230
  memcpy((char*)m_tmpPtr + m_pFilter->fieldOffset(i), m_ptr + offset,
@@ -222,6 +236,7 @@ public:
222
236
  }
223
237
  else if (m_tb->valiableFormatType())
224
238
  {
239
+ memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
225
240
  memcpy(m_tmpPtr, m_ptr, m_len);
226
241
  m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
227
242
  m_tb->setBlobFieldPointer(m_tmpPtr, m_hd);
@@ -252,6 +267,7 @@ public:
252
267
  inline int rowCount() const {return m_rowCount;}
253
268
  inline bool isEndOfRow(unsigned int row) const {return (m_rowCount && (row == m_rowCount));}
254
269
  inline bool withinCache(unsigned int row) const {return (row < m_rowCount);}
270
+ inline short_td seekMultiStat(){return m_seekMultiStat;}
255
271
  };
256
272
 
257
273
  // ---------------------------------------------------------------------------
@@ -286,6 +302,7 @@ inline __int64 getValue64(const fielddef& fd, const uchar_td* ptr)
286
302
  case 8: ret = *((__int64*)(ptr + fd.pos));
287
303
  break;
288
304
  }
305
+ case ft_autoIncUnsigned:
289
306
  case ft_uinteger:
290
307
  case ft_logical:
291
308
  case ft_bit:
@@ -332,10 +349,11 @@ inline void setValue(const fielddef& fd, uchar_td* ptr, __int64 value)
332
349
  break;
333
350
  case 4: *((int*)(ptr + fd.pos)) = (int)value;
334
351
  break;
335
- case 8: *((__int64*)(ptr + fd.pos)) = (int)value;
352
+ case 8: *((__int64*)(ptr + fd.pos)) = value;
336
353
  break;
337
354
  }
338
355
  }
356
+ case ft_autoIncUnsigned:
339
357
  case ft_uinteger:
340
358
  case ft_logical:
341
359
  case ft_bit:
@@ -346,7 +364,8 @@ inline void setValue(const fielddef& fd, uchar_td* ptr, __int64 value)
346
364
  case ft_mytime:
347
365
  case ft_mydate:
348
366
  case ft_mydatetime:
349
- case ft_mytimestamp: memcpy(ptr + fd.pos, &value, fd.len);
367
+ case ft_mytimestamp:
368
+ memcpy(ptr + fd.pos, &value, fd.len);
350
369
  break;
351
370
  }
352
371
  }
@@ -431,57 +450,51 @@ inline short calcNextReadRecordCount(ushort_td curCount, int eTime)
431
450
  else
432
451
  ret = (ushort_td)(curCount * ((float)100 / (float)eTime));
433
452
 
434
- if (ret > 10000)
435
- return 10000;
453
+ if (ret > 9500)
454
+ return 9500;
436
455
  if (ret == 0)
437
456
  return 1;
438
457
  return ret;
439
458
  }
440
459
 
441
- uint_td table::doRecordCount(bool estimate, bool fromCurrent)
460
+ uint_td table::doRecordCount(bool estimate, bool fromCurrent, eFindType direction)
442
461
  {
443
462
  uint_td result = 0;
444
463
 
445
464
  if (m_impl->filterPtr)
446
465
  {
466
+ short_td op = (direction == findForword) ? TD_KEY_NEXT_MULTI:TD_KEY_PREV_MULTI;
467
+
468
+ if (tableDef()->keyCount == 0)
469
+ op += TD_POS_NEXT_MULTI - TD_KEY_NEXT_MULTI;// KEY to POS
447
470
  short curStat = m_stat;
448
471
  m_impl->exBookMarking = true;
449
- ushort_td recCountOnce = 50;
472
+ ushort_td recCountOnce = 100;
450
473
 
451
474
  bookmark_td bm = bookmark();
452
- ushort_td tmpFieldCount = m_impl->filterPtr->fieldCount();
475
+
453
476
  ushort_td tmpRejectCount = m_impl->filterPtr->rejectCount();
454
477
  ushort_td tmpRecCount = m_impl->filterPtr->recordCount();
455
- _TCHAR* str = new _TCHAR[_tcslen(filterStr()) + 1];
456
- if (str)
457
- {
458
- _tcscpy(str, filterStr());
459
- m_impl->filterPtr->setFieldCount(0);
460
- m_stat = 0;
461
- m_impl->filterPtr->setFilter(str, tmpRejectCount, 10000);
462
- if (m_stat != 0)
463
- {
464
- // restore filter string
465
- m_impl->filterPtr->setFieldCount(tmpFieldCount);
466
- m_impl->filterPtr->setFilter(str, tmpRejectCount, tmpRecCount);
467
- delete[]str;
468
- str = NULL;
469
- }
470
- }
471
- else
472
- assert(0);
478
+
479
+ m_impl->filterPtr->setIgnoreFields(true);
473
480
  m_impl->maxBookMarkedCount = 0;
474
481
  if (fromCurrent)
475
482
  m_stat = curStat;
476
- else
483
+ else if (op == TD_KEY_NEXT_MULTI)
477
484
  seekFirst();
478
-
479
- *(m_impl->filterPtr->recordCountDirect()) = recCountOnce;
485
+ else if (op == TD_KEY_PREV_MULTI)
486
+ seekLast();
487
+ else if (op == TD_POS_NEXT_MULTI)
488
+ stepFirst();
489
+ else if (op == TD_POS_PREV_MULTI)
490
+ stepLast();
491
+
492
+ m_impl->filterPtr->setMaxRows(recCountOnce);
480
493
  if (m_stat == 0)
481
494
  {
482
495
  m_impl->filterPtr->setPosTypeNext(false);
483
496
  boost::timer t;
484
- btrvGetExtend(TD_KEY_NEXT_MULTI);
497
+ btrvGetExtend(op);
485
498
  int eTime = (int)(t.elapsed() * 1000);
486
499
  while ((m_stat == 0) || (m_stat == STATUS_LIMMIT_OF_REJECT) || (m_stat == STATUS_EOF)
487
500
  || (m_stat == STATUS_REACHED_FILTER_COND))
@@ -502,35 +515,34 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
502
515
  }
503
516
  }
504
517
  recCountOnce = calcNextReadRecordCount(recCountOnce, eTime);
505
-
506
- *(m_impl->filterPtr->recordCountDirect()) = recCountOnce;
518
+ m_impl->filterPtr->setMaxRows(recCountOnce);
507
519
  result += *((ushort_td*)m_impl->dataBak);
508
520
  setBookMarks(m_impl->maxBookMarkedCount + 1, (void*)((char*)m_impl->dataBak + 2),
509
521
  *((ushort_td*)m_impl->dataBak));
510
522
  m_impl->maxBookMarkedCount = result;
511
-
512
523
  onRecordCounting(result, Complete);
513
524
  if (Complete)
514
525
  break;
515
526
  t.restart();
516
527
  m_impl->filterPtr->setPosTypeNext(true);
517
- btrvGetExtend(TD_KEY_NEXT_MULTI);
528
+ btrvGetExtend(op);
518
529
  eTime = (int)(t.elapsed() * 1000);
519
530
  }
520
531
  }
532
+
521
533
  short tmpStat = m_stat;
522
- if (str)
523
- {
524
- setFilter(str, tmpRejectCount, tmpRecCount);
525
- delete[]str;
526
- }
534
+ m_impl->filterPtr->setIgnoreFields(false);
535
+ m_impl->filterPtr->setMaxRows(tmpRecCount);
536
+
527
537
  if (bm)
528
538
  seekByBookmark(bm);
529
539
  m_impl->exBookMarking = false;
530
540
  m_stat = tmpStat;
541
+ if (m_stat == STATUS_EOF)
542
+ m_stat = 0;
531
543
  }
532
544
  else
533
- return nstable::doRecordCount(estimate, fromCurrent);
545
+ return nstable::doRecordCount(estimate, fromCurrent, direction);
534
546
 
535
547
  return result;
536
548
  }
@@ -540,11 +552,26 @@ void table::btrvGetExtend(ushort_td op)
540
552
 
541
553
  if (op >= TD_KEY_GE_NEXT_MULTI)
542
554
  m_keylen = writeKeyData();
555
+
543
556
  m_pdata = m_impl->dataBak;
544
- m_impl->filterPtr->WriteBuffer();
557
+ if (!m_impl->filterPtr->writeBuffer())
558
+ {
559
+ m_stat = STATUS_WARKSPACE_TOO_SMALL;
560
+ return;
561
+ }
545
562
  m_datalen = m_impl->filterPtr->exDataBufLen();
563
+
564
+ //cacheing direction
565
+ if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI)|| (op == TD_POS_PREV_MULTI))
566
+ m_impl->filterPtr->setDirection(findBackForword);
567
+ else
568
+ m_impl->filterPtr->setDirection(findForword);
569
+
546
570
  tdap(op);
547
571
  short stat = m_stat;
572
+ if (!m_impl->filterPtr->isWriteComleted() && (stat == STATUS_REACHED_FILTER_COND))
573
+ stat = STATUS_LIMMIT_OF_REJECT;
574
+
548
575
  m_impl->rc->reset(m_impl->filterPtr, (char*)m_impl->dataBak, m_datalen, blobFieldUsed() ?
549
576
  getBlobHeader() : NULL);
550
577
 
@@ -554,13 +581,11 @@ void table::btrvGetExtend(ushort_td op)
554
581
  if (m_impl->rc->rowCount() && (!m_impl->exBookMarking))
555
582
  {
556
583
  m_pdata = (void*)m_impl->rc->setRow(0);
557
- m_datalen = m_impl->rc->len();
584
+ m_datalen = tableDef()->maxRecordLen;//m_impl->rc->len();
558
585
 
559
- m_stat = STATUS_SUCCESS;
586
+ m_stat = m_impl->rc->seekMultiStat();
560
587
  }else if ((m_stat == STATUS_LIMMIT_OF_REJECT) && (m_impl->filterPtr->rejectCount()>=1))
561
588
  m_stat = STATUS_EOF;
562
-
563
-
564
589
  }
565
590
 
566
591
  void table::getRecords(ushort_td op)
@@ -586,24 +611,40 @@ bookmark_td table::bookmarkFindCurrent() const
586
611
 
587
612
  void table::find(eFindType type)
588
613
  {
614
+ ushort_td op;
615
+
616
+ if (m_impl->filterPtr->isSeeksMode())
617
+ {
618
+ m_impl->filterPtr->resetSeeksWrited();
619
+ op = TD_KEY_SEEK_MULTI;
620
+ }
621
+ else
622
+ op = (type == findForword) ? TD_KEY_GE_NEXT_MULTI:TD_KEY_LE_PREV_MULTI;
623
+
589
624
  if (nsdb()->isUseTransactd())
590
625
  {
591
626
  m_impl->rc->reset();
592
- ushort_td op = (type == findForword) ? TD_KEY_GE_NEXT_MULTI:TD_KEY_LE_PREV_MULTI;
593
627
  doFind(op, true/*notIncCurrent*/);
594
628
  }
595
629
  else
596
630
  {
631
+
632
+ if (op == TD_KEY_SEEK_MULTI)
633
+ {
634
+ //P.SQL not support TD_KEY_SEEK_MULTI
635
+ m_stat = STATUS_FILTERSTRING_ERROR;
636
+ return;
637
+ }
597
638
  if (type == findForword)
598
- seekGreater(true);
639
+ seekGreater(false);
599
640
  else
600
- seekLessThan(true);
641
+ seekLessThan(false);
601
642
  if (m_stat == 0)
602
643
  {
603
644
  if (type == findForword)
604
- findNext(true);
645
+ findNext(false);
605
646
  else
606
- findPrev(true);
647
+ findPrev(false);
607
648
  }
608
649
  }
609
650
 
@@ -617,6 +658,7 @@ void table::findFirst()
617
658
  {
618
659
  if (m_impl->filterPtr)
619
660
  {
661
+
620
662
  m_impl->exNext = 1;
621
663
  m_impl->filterPtr->setPosTypeNext(false);
622
664
  getRecords(TD_KEY_NEXT_MULTI);
@@ -631,6 +673,7 @@ void table::findLast()
631
673
  {
632
674
  if (m_impl->filterPtr)
633
675
  {
676
+
634
677
  m_impl->exNext = -1;
635
678
  m_impl->filterPtr->setPosTypeNext(false);
636
679
  getRecords(TD_KEY_PREV_MULTI);
@@ -638,6 +681,21 @@ void table::findLast()
638
681
  }
639
682
  }
640
683
 
684
+ bool table::checkFindDirection(ushort_td op)
685
+ {
686
+ bool ret ;
687
+ if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI))
688
+ ret = (m_impl->filterPtr->direction() == findBackForword);
689
+ else
690
+ ret = (m_impl->filterPtr->direction() == findForword);
691
+ if (!ret)
692
+ {
693
+ assert(0);
694
+ m_stat = 1;
695
+ }
696
+ return ret;
697
+ }
698
+
641
699
  void table::doFind( ushort_td op, bool notIncCurrent)
642
700
  {
643
701
  /*
@@ -650,12 +708,27 @@ void table::doFind( ushort_td op, bool notIncCurrent)
650
708
 
651
709
  if (m_impl->rc->withinCache(row) && (!m_impl->exBookMarking))
652
710
  { /* read from cache */
711
+
712
+ /*Is direction same */
713
+ if (!checkFindDirection(op))
714
+ return ;
715
+
653
716
  m_pdata = (void*)m_impl->rc->setRow(row);
654
- m_datalen = m_impl->rc->len();
717
+ m_stat = m_impl->rc->seekMultiStat();
718
+
719
+ /*set keyvalue for keyValueDescription*/
720
+ if (m_stat != 0)
721
+ setSeekValueField(row);
722
+
723
+ //m_datalen = m_impl->rc->len();
724
+ m_datalen = tableDef()->maxRecordLen;
655
725
  }
656
726
  else if (m_impl->rc->isEndOfRow(row))
657
727
  {
658
728
  /* whole row readed */
729
+ /*Is direction same */
730
+ if (!checkFindDirection(op))
731
+ return ;
659
732
  /* A special situation that if rejectCount() == 0 and status = STATUS_LIMMIT_OF_REJECT
660
733
  then it continues . */
661
734
  if ((m_impl->exSlideStat == 0)
@@ -685,7 +758,11 @@ void table::findNext(bool notIncCurrent)
685
758
  {
686
759
 
687
760
  if (m_impl->filterPtr)
688
- doFind(TD_KEY_NEXT_MULTI, notIncCurrent);
761
+ {
762
+ short op = m_impl->filterPtr->isSeeksMode() ? TD_KEY_SEEK_MULTI
763
+ : TD_KEY_NEXT_MULTI;
764
+ doFind(op, notIncCurrent);
765
+ }
689
766
  else if (notIncCurrent == true)
690
767
  seekNext();
691
768
  }
@@ -699,7 +776,7 @@ void table::findPrev(bool notIncCurrent)
699
776
 
700
777
  }
701
778
 
702
- void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCount)
779
+ void table::setQuery(const queryBase* query)
703
780
  {
704
781
 
705
782
  m_stat = 0;
@@ -708,7 +785,7 @@ void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCo
708
785
  m_impl->exBookMarking = false;
709
786
  m_impl->exSlideStat = 0;
710
787
  m_impl->exNext = 0;
711
- if (str[0] == 0x00)
788
+ if (query == NULL)
712
789
  {
713
790
  m_impl->maxBookMarkedCount = 0;
714
791
  delete m_impl->filterPtr;
@@ -725,7 +802,8 @@ void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCo
725
802
  return;
726
803
 
727
804
  }
728
- if (!m_impl->filterPtr->setFilter(str, RejectCount, CashCount))
805
+
806
+ if (!m_impl->filterPtr->setQuery(query))
729
807
  {
730
808
  m_stat = STATUS_FILTERSTRING_ERROR;
731
809
  delete m_impl->filterPtr;
@@ -734,9 +812,9 @@ void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCo
734
812
  }
735
813
  if (!m_impl->bookMarks)
736
814
  {
737
- m_impl->bookMarks = malloc(40960);
815
+ m_impl->bookMarks = malloc(BOOKMARK_ALLOC_SIZE);
738
816
  if (m_impl->bookMarks)
739
- m_impl->bookMarksMemSize = 40960;
817
+ m_impl->bookMarksMemSize = BOOKMARK_ALLOC_SIZE;
740
818
  else
741
819
  {
742
820
  m_stat = STATUS_FILTERSTRING_ERROR;
@@ -746,6 +824,19 @@ void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCo
746
824
  }
747
825
  }
748
826
 
827
+ void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCount)
828
+ {
829
+ if (!str || (str[0] == 0x00))
830
+ setQuery(NULL);
831
+ else
832
+ {
833
+ queryBase q;
834
+ q.queryString(str).reject(RejectCount).limit(CashCount);
835
+ setQuery(&q);
836
+ }
837
+
838
+ }
839
+
749
840
  const _TCHAR* table::filterStr()
750
841
  {
751
842
  if (m_impl->filterPtr)
@@ -756,8 +847,10 @@ const _TCHAR* table::filterStr()
756
847
 
757
848
  void table::clearBuffer()
758
849
  {
850
+ m_impl->rc->reset();
851
+ m_pdata = m_impl->dataBak;
759
852
  memset(m_pdata, 0x00, m_buflen);
760
- if (blobFieldUsed())
853
+ if ((bulkIns()==NULL) && blobFieldUsed())
761
854
  resetSendBlob();
762
855
 
763
856
  }
@@ -867,7 +960,8 @@ bool table::onUpdateCheck(eUpdateType type)
867
960
  void table::onUpdateAfter(int beforeResult)
868
961
  {
869
962
  if (blobFieldUsed())
870
- resetSendBlob();
963
+ addSendBlob(NULL);
964
+
871
965
  if (valiableFormatType() && m_impl->dataPacked)
872
966
  m_datalen = unPack((char*)m_pdata, m_datalen);
873
967
 
@@ -892,16 +986,23 @@ ushort_td table::doCommitBulkInsert(bool autoCommit)
892
986
  {
893
987
  ushort_td ret = nstable::doCommitBulkInsert(autoCommit);
894
988
  if (blobFieldUsed())
895
- resetSendBlob();
989
+ addSendBlob(NULL);
896
990
  return ret;
897
991
  }
898
992
 
993
+ void table::doAbortBulkInsert()
994
+ {
995
+ nstable::doAbortBulkInsert();
996
+ if (blobFieldUsed())
997
+ addSendBlob(NULL);
998
+ }
999
+
899
1000
  void table::onInsertAfter(int beforeResult)
900
1001
  {
901
1002
  if (valiableFormatType() && m_impl->dataPacked)
902
1003
  m_datalen = unPack((char*)m_pdata, m_datalen);
903
- if (blobFieldUsed())
904
- resetSendBlob();
1004
+ if ((bulkIns()==NULL) && blobFieldUsed())
1005
+ addSendBlob(NULL);
905
1006
  }
906
1007
 
907
1008
  void* table::attachBuffer(void* NewPtr, bool unpack, size_t size)
@@ -1119,9 +1220,11 @@ void table::resetSendBlob()
1119
1220
  void table::addSendBlob(const blob* blob)
1120
1221
  {
1121
1222
  short stat = m_stat;
1223
+ /*backup current data buffer*/
1122
1224
  const void *tmp = data();
1123
1225
  setData((void*)blob);
1124
1226
  tdap(TD_ADD_SENDBLOB);
1227
+ /*restore data buffer*/
1125
1228
  setData((void*)tmp);
1126
1229
  m_stat = stat;
1127
1230
  }
@@ -1130,9 +1233,11 @@ const blobHeader* table::getBlobHeader()
1130
1233
  {
1131
1234
  short stat = m_stat;
1132
1235
  const blobHeader* p;
1236
+ /*backup current data buffer*/
1133
1237
  const void *tmp = data();
1134
1238
  setData(&p);
1135
1239
  tdap(TD_GET_BLOB_BUF);
1240
+ /*restore data buffer*/
1136
1241
  setData((void*)tmp);
1137
1242
  std::swap(stat, m_stat);
1138
1243
 
@@ -1171,7 +1276,7 @@ void table::onReadAfter()
1171
1276
  {
1172
1277
  m_datalen = unPack((char*)m_pdata, m_datalen);
1173
1278
  if (m_datalen == 0)
1174
- m_stat = 22;
1279
+ m_stat = STATUS_BUFFERTOOSMALL;
1175
1280
  }
1176
1281
  if (blobFieldUsed())
1177
1282
  {
@@ -1276,6 +1381,7 @@ void table::setFVA(short index, const char* data)
1276
1381
  case ft_time: // time hh:nn:ss
1277
1382
  value = /*StrToBtrTime*/atobtrt((const char*)data).i;
1278
1383
  break;
1384
+ case ft_autoIncUnsigned:
1279
1385
  case ft_uinteger:
1280
1386
  case ft_integer:
1281
1387
  case ft_autoinc:
@@ -1375,6 +1481,7 @@ void table::setFVW(short index, const wchar_t* data)
1375
1481
  setFV(index, value);
1376
1482
  return;
1377
1483
 
1484
+ case ft_autoIncUnsigned:
1378
1485
  case ft_uinteger:
1379
1486
  case ft_integer:
1380
1487
  case ft_autoinc:
@@ -1485,6 +1592,7 @@ void table::setFV(short index, int data)
1485
1592
  case ft_integer:
1486
1593
  case ft_date:
1487
1594
  case ft_time:
1595
+ case ft_autoIncUnsigned:
1488
1596
  case ft_uinteger:
1489
1597
  case ft_logical:
1490
1598
  case ft_autoinc:
@@ -1593,6 +1701,7 @@ void table::setFV(short index, double data)
1593
1701
  case ft_integer:
1594
1702
  case ft_date:
1595
1703
  case ft_time:
1704
+ case ft_autoIncUnsigned:
1596
1705
  case ft_uinteger:
1597
1706
  case ft_logical:
1598
1707
  case ft_autoinc:
@@ -1684,6 +1793,7 @@ int table::getFVlng(short index)
1684
1793
  break;
1685
1794
  }
1686
1795
  break;
1796
+ case ft_autoIncUnsigned:
1687
1797
  case ft_uinteger:
1688
1798
  case ft_logical:
1689
1799
  case ft_bit:
@@ -1794,6 +1904,7 @@ double table::getFVdbl(short index)
1794
1904
  case ft_integer:
1795
1905
  case ft_date:
1796
1906
  case ft_time:
1907
+ case ft_autoIncUnsigned:
1797
1908
  case ft_uinteger:
1798
1909
  case ft_logical:
1799
1910
  case ft_autoinc:
@@ -1903,7 +2014,9 @@ const wchar_t* table::getFVWstr(short index)
1903
2014
  }
1904
2015
  break;
1905
2016
  }
1906
- case ft_uinteger: swprintf_s(p, 50, L"%u", getFVlng(index));
2017
+ case ft_autoIncUnsigned:
2018
+ case ft_uinteger:
2019
+ swprintf_s(p, 50, L"%lu", getFV64(index));
1907
2020
  break;
1908
2021
  case ft_date: return btrdtoa(getFVlng(index), p);
1909
2022
  case ft_time: return btrttoa(getFVlng(index), p);
@@ -2038,7 +2151,9 @@ const char* table::getFVAstr(short index)
2038
2151
  }
2039
2152
  case ft_date: return btrdtoa(getFVlng(index), p);
2040
2153
  case ft_time: return btrttoa(getFVlng(index), p);
2041
- case ft_uinteger: sprintf(p, "%u", getFVlng(index));
2154
+ case ft_autoIncUnsigned:
2155
+ case ft_uinteger:
2156
+ sprintf_s(p, 50, "%lu", getFV64(index));
2042
2157
  break;
2043
2158
 
2044
2159
  case ft_mydate:
@@ -2185,6 +2300,7 @@ __int64 table::getFV64(short index)
2185
2300
  case 8:
2186
2301
  switch (fd.type)
2187
2302
  {
2303
+ case ft_autoIncUnsigned:
2188
2304
  case ft_uinteger:
2189
2305
  case ft_integer:
2190
2306
  case ft_logical:
@@ -2229,6 +2345,7 @@ void table::setFV(short index, __int64 data)
2229
2345
  case 8:
2230
2346
  switch (fd.type)
2231
2347
  {
2348
+ case ft_autoIncUnsigned:
2232
2349
  case ft_uinteger:
2233
2350
  case ft_integer:
2234
2351
  case ft_logical:
@@ -2578,10 +2695,6 @@ unsigned int table::getRecordHash()
2578
2695
  return hash((const char*)fieldPtr(0), datalen());
2579
2696
  }
2580
2697
 
2581
-
2582
-
2583
-
2584
-
2585
2698
  int table::bookMarksCount() const
2586
2699
  {
2587
2700
  int ret;
@@ -2604,6 +2717,337 @@ short_td table::doBtrvErr(HWND hWnd, _TCHAR* retbuf)
2604
2717
  return nstable::tdapErr(hWnd, m_stat, m_tableDef->tableName(), retbuf);
2605
2718
  }
2606
2719
 
2720
+ /* For keyValueDescription */
2721
+ bool table::setSeekValueField(int row)
2722
+ {
2723
+ const std::vector<std::_tstring>& keyValues = m_impl->filterPtr->keyValuesCache();
2724
+ keydef* kd = &tableDef()->keyDefs[keyNum()];
2725
+ if (keyValues.size() % kd->segmentCount)
2726
+ return false;
2727
+ //Check uniqe key
2728
+ if (kd->segments[0].flags.bit0)
2729
+ return false;
2730
+
2731
+ size_t pos = kd->segmentCount * row;
2732
+ for (int j=0;j<kd->segmentCount;++j)
2733
+ setFV(kd->segments[j].fieldNum, keyValues[pos+j].c_str());
2734
+ return true;
2735
+ }
2736
+
2737
+ void table::keyValueDescription(_TCHAR* buf, int bufsize)
2738
+ {
2739
+
2740
+ std::_tstring s;
2741
+ if (stat() == STATUS_NOT_FOUND_TI)
2742
+ {
2743
+
2744
+ for (int i=0;i<tableDef()->keyDefs[keyNum()].segmentCount;i++)
2745
+ {
2746
+ short fnum = tableDef()->keyDefs[keyNum()].segments[i].fieldNum;
2747
+ s += std::_tstring(tableDef()->fieldDefs[fnum].name())
2748
+ + _T(" = ") + getFVstr(fnum) + _T("\n");
2749
+ }
2750
+ }
2751
+ else if (stat() == STATUS_DUPPLICATE_KEYVALUE)
2752
+ {
2753
+ _TCHAR tmp[50];
2754
+ for (int j=0;j<tableDef()->keyCount;j++)
2755
+ {
2756
+ _stprintf_s(tmp, 50, _T("[key%d]\n"), j);
2757
+ s += tmp;
2758
+ for (int i=0;i<tableDef()->keyDefs[j].segmentCount;i++)
2759
+ {
2760
+ short fnum = tableDef()->keyDefs[j].segments[i].fieldNum;
2761
+ s += std::_tstring(tableDef()->fieldDefs[fnum].name())
2762
+ + _T(" = ") + getFVstr(fnum) + _T("\n");
2763
+ }
2764
+ }
2765
+
2766
+ }
2767
+
2768
+ _stprintf_s(buf, bufsize, _T("table:%s\nstat:%d\n%s")
2769
+ ,tableDef()->tableName()
2770
+ ,stat()
2771
+ ,s.c_str());
2772
+ }
2773
+
2774
+
2775
+ //-------------------------------------------------------------------
2776
+ // class queryBase
2777
+ //-------------------------------------------------------------------
2778
+ typedef boost::escaped_list_separator<_TCHAR> esc_sep;
2779
+ typedef boost::tokenizer<esc_sep
2780
+ ,std::_tstring::const_iterator
2781
+ ,std::_tstring> tokenizer;
2782
+
2783
+ void analyzeQuery(const _TCHAR* str
2784
+ , std::vector<std::_tstring>& selects
2785
+ , std::vector<std::_tstring>& where
2786
+ , std::vector<std::_tstring>& keyValues
2787
+ ,bool& nofilter)
2788
+ {
2789
+ esc_sep sep(_T('&'), _T(' '), _T('\''));
2790
+ std::_tstring s = str;
2791
+ tokenizer tokens(s, sep);
2792
+
2793
+ tokenizer::iterator it = tokens.begin();
2794
+ if (it == tokens.end()) return;
2795
+ if (*it == _T("*"))
2796
+ {
2797
+ nofilter = true;
2798
+ return;
2799
+ }
2800
+ s = *it;
2801
+ boost::algorithm::to_lower(s);
2802
+ if (s == _T("select"))
2803
+ {
2804
+ tokenizer::iterator itTmp = it;
2805
+ s = *(++it);
2806
+ if (getFilterLogicTypeCode(s.c_str())==255)
2807
+ {
2808
+ esc_sep sep(_T('&'), _T(','), _T('\''));
2809
+ tokenizer fields(s, sep);
2810
+ tokenizer::iterator itf = fields.begin();
2811
+ while (itf != fields.end())
2812
+ selects.push_back(*(itf++));
2813
+ ++it;
2814
+ }else
2815
+ it = itTmp; // field name is select
2816
+ }
2817
+ if (it == tokens.end())
2818
+ return;
2819
+ s = *it;
2820
+ boost::algorithm::to_lower(s);
2821
+ bool enableWhere = true;
2822
+ if (s == _T("in"))
2823
+ {
2824
+ tokenizer::iterator itTmp = it;
2825
+ s = *(++it);
2826
+ if (getFilterLogicTypeCode(s.c_str())==255)
2827
+ {
2828
+ enableWhere = false;
2829
+ esc_sep sep(_T('&'), _T(','), _T('\''));
2830
+ tokenizer values(s, sep);
2831
+ tokenizer::iterator itf = values.begin();
2832
+ while (itf != values.end())
2833
+ keyValues.push_back(*(itf++));
2834
+ }else
2835
+ it = itTmp; // field name is in
2836
+ }
2837
+ if (enableWhere)
2838
+ {
2839
+ while (it != tokens.end())
2840
+ where.push_back(*(it++));
2841
+ }
2842
+
2843
+ }
2844
+
2845
+
2846
+ struct impl
2847
+ {
2848
+ impl():
2849
+ m_reject(1),m_limit(0),m_direction(table::findForword)
2850
+ ,m_nofilter(false),m_optimize(false){}
2851
+
2852
+ int m_reject;
2853
+ int m_limit;
2854
+ table::eFindType m_direction;
2855
+ bool m_nofilter;
2856
+ bool m_optimize;
2857
+ mutable std::_tstring m_str;
2858
+ std::vector<std::_tstring> m_selects;
2859
+ std::vector<std::_tstring> m_wheres;
2860
+ std::vector<std::_tstring> m_keyValues;
2861
+ };
2862
+
2863
+ queryBase::queryBase():m_impl(new impl){}
2864
+
2865
+ queryBase::~queryBase()
2866
+ {
2867
+ delete m_impl;
2868
+ }
2869
+
2870
+ void queryBase::reset()
2871
+ {
2872
+ delete m_impl;
2873
+ m_impl = new impl;
2874
+ }
2875
+
2876
+ void queryBase::clearSelectFields()
2877
+ {
2878
+ m_impl->m_selects.clear();
2879
+ }
2880
+
2881
+ void queryBase::addField(const _TCHAR* name)
2882
+ {
2883
+ m_impl->m_selects.push_back(name);
2884
+ m_impl->m_nofilter = false;
2885
+ }
2886
+
2887
+ void queryBase::addLogic(const _TCHAR* name, const _TCHAR* logic, const _TCHAR* value)
2888
+ {
2889
+ m_impl->m_keyValues.clear();
2890
+ m_impl->m_wheres.clear();
2891
+ m_impl->m_wheres.push_back(name);
2892
+ m_impl->m_wheres.push_back(logic);
2893
+ m_impl->m_wheres.push_back(value);
2894
+ m_impl->m_nofilter = false;
2895
+
2896
+ }
2897
+
2898
+ void queryBase::addLogic(const _TCHAR* combine, const _TCHAR* name
2899
+ , const _TCHAR* logic, const _TCHAR* value)
2900
+ {
2901
+ m_impl->m_wheres.push_back(combine);
2902
+ m_impl->m_wheres.push_back(name);
2903
+ m_impl->m_wheres.push_back(logic);
2904
+ m_impl->m_wheres.push_back(value);
2905
+ m_impl->m_nofilter = false;
2906
+
2907
+ }
2908
+
2909
+ void queryBase::addSeekKeyValue(const _TCHAR* value, bool reset)
2910
+ {
2911
+ if (reset)
2912
+ {
2913
+ m_impl->m_wheres.clear();
2914
+ m_impl->m_keyValues.clear();
2915
+ }
2916
+ m_impl->m_keyValues.push_back(value);
2917
+ //m_impl->m_reject = 1;
2918
+ m_impl->m_nofilter = false;
2919
+
2920
+ }
2921
+
2922
+ void queryBase::clearSeekKeyValues()
2923
+ {
2924
+ m_impl->m_keyValues.clear();
2925
+ }
2926
+
2927
+ queryBase& queryBase::queryString(const _TCHAR* str)
2928
+ {
2929
+ m_impl->m_selects.clear();
2930
+ m_impl->m_wheres.clear();
2931
+ m_impl->m_keyValues.clear();
2932
+ m_impl->m_nofilter = false;
2933
+ if (str && str[0])
2934
+ analyzeQuery(str, m_impl->m_selects, m_impl->m_wheres, m_impl->m_keyValues
2935
+ ,m_impl->m_nofilter);
2936
+ return *this;
2937
+ }
2938
+
2939
+ queryBase& queryBase::reject(int v)
2940
+ {
2941
+ m_impl->m_reject = v;
2942
+ return *this;
2943
+ }
2944
+
2945
+ queryBase& queryBase::limit(int v)
2946
+ {
2947
+ m_impl->m_limit = v;
2948
+ return *this;
2949
+ }
2950
+
2951
+ queryBase& queryBase::direction(table::eFindType v)
2952
+ {
2953
+ m_impl->m_direction = v;
2954
+ return *this;
2955
+ }
2956
+
2957
+ queryBase& queryBase::all()
2958
+ {
2959
+ reset();
2960
+ m_impl->m_nofilter = true;
2961
+ return *this;
2962
+ }
2963
+
2964
+ queryBase& queryBase::optimize(bool v)
2965
+ {
2966
+ m_impl->m_optimize = v;
2967
+ return *this;
2968
+ }
2969
+
2970
+ bool queryBase::isOptimize()const
2971
+ {
2972
+ return m_impl->m_optimize;
2973
+ }
2974
+
2975
+ table::eFindType queryBase::getDirection() const {return m_impl->m_direction;}
2976
+
2977
+ std::_tstring escape_value(std::_tstring s)
2978
+ {
2979
+ std::_tstring::iterator it = s.begin();
2980
+ for (int i=(int)s.size()-1;i>=0;--i)
2981
+ {
2982
+ if (s[i] == _T('&'))
2983
+ s.insert(s.begin()+i, _T('&'));
2984
+ else if (s[i] == _T('\''))
2985
+ s.insert(s.begin()+i, _T('&'));
2986
+ }
2987
+ return s;
2988
+ }
2989
+
2990
+ const _TCHAR* queryBase::toString() const
2991
+ {
2992
+ m_impl->m_str.clear();
2993
+ if (m_impl->m_nofilter)
2994
+ return _T("*");
2995
+
2996
+ std::_tstring& s = m_impl->m_str;
2997
+ std::vector<std::_tstring>& selects = m_impl->m_selects;
2998
+ std::vector<std::_tstring>& wheres = m_impl->m_wheres;
2999
+ std::vector<std::_tstring>& keyValues = m_impl->m_keyValues;
3000
+ if (selects.size())
3001
+ {
3002
+ s = _T("select ");
3003
+ for (int i= 0;i < (int)selects.size();++i)
3004
+ s += selects[i] + _T(",");
3005
+
3006
+ if (s.size())
3007
+ s.replace(s.size()-1,1, _T(" "));
3008
+ }
3009
+
3010
+ for (size_t i= 0;i < wheres.size();i+=4)
3011
+ {
3012
+ s += wheres[i] + _T(" ") + wheres[i+1] + _T(" '")
3013
+ + escape_value(wheres[i+2]) + _T("' ");
3014
+ if (i+3 < wheres.size())
3015
+ s += wheres[i+3] + _T(" ");
3016
+ }
3017
+
3018
+ if (keyValues.size())
3019
+ {
3020
+ s += _T("in ");
3021
+ for (size_t i= 0;i < keyValues.size();++i)
3022
+ s += _T("'") + escape_value(keyValues[i]) + _T("',");
3023
+ }
3024
+ if (s.size())
3025
+ s.erase(s.end() -1);
3026
+
3027
+
3028
+ return s.c_str();
3029
+ }
3030
+
3031
+ int queryBase::getReject()const{return m_impl->m_reject;}
3032
+
3033
+ int queryBase::getLimit()const{return m_impl->m_limit;}
3034
+
3035
+ bool queryBase::isAll()const{return m_impl->m_nofilter;};
3036
+
3037
+ const std::vector<std::_tstring>& queryBase::getSelects() const {return m_impl->m_selects;}
3038
+ const std::vector<std::_tstring>& queryBase::getWheres() const {return m_impl->m_wheres;}
3039
+ const std::vector<std::_tstring>& queryBase::getSeekKeyValues() const{return m_impl->m_keyValues;}
3040
+
3041
+ void queryBase::release()
3042
+ {
3043
+ delete this;
3044
+ }
3045
+
3046
+ queryBase* queryBase::create()
3047
+ {
3048
+ return new queryBase();
3049
+
3050
+ }
2607
3051
 
2608
3052
 
2609
3053
  }// namespace client