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
@@ -19,6 +19,7 @@
19
19
  #pragma hdrstop
20
20
  #include "groupQuery.h"
21
21
  #include "recordsetImple.h"
22
+ #include "filter.h"
22
23
  #include <boost/algorithm/string.hpp>
23
24
 
24
25
  #pragma package(smart_init)
@@ -152,15 +153,20 @@ void fieldNames::addValues(const _TCHAR* values, const _TCHAR* delmi)
152
153
  struct recordsetQueryImple
153
154
  {
154
155
  row_ptr row;
155
- std::vector<unsigned char> compType;
156
- std::vector<short> indexes;
157
- std::vector<char> combine;
156
+ struct compItem
157
+ {
158
+ compFieldFunc compFunc;
159
+ short index;
160
+ unsigned char compType;
161
+ char combine;
162
+ };
163
+ std::vector<compItem> compItems;
164
+
158
165
  short endIndex;
159
166
  fielddefs compFields;
160
167
  recordsetQueryImple() : row(NULL) {}
161
168
  recordsetQueryImple(const recordsetQueryImple& r)
162
- : row(r.row), compType(r.compType), indexes(r.indexes),
163
- combine(r.combine), endIndex(r.endIndex), compFields(r.compFields)
169
+ : row(r.row), compItems(r.compItems), compFields(r.compFields)
164
170
  {
165
171
  if (row)
166
172
  row->addref();
@@ -214,13 +220,14 @@ recordsetQuery::~recordsetQuery()
214
220
  void recordsetQuery::init(const fielddefs* fdinfo)
215
221
  {
216
222
  const std::vector<std::_tstring>& tokns = getWheres();
217
- m_imple->indexes.clear();
218
223
  m_imple->compFields.clear();
224
+ m_imple->compItems.clear();
219
225
  for (int i = 0; i < (int)tokns.size(); i += 4)
220
226
  {
221
- int index = fdinfo->indexByName(tokns[i].c_str());
222
- m_imple->indexes.push_back(index);
223
- m_imple->compFields.push_back(&((*fdinfo)[index]), true /*rePosition*/);
227
+ recordsetQueryImple::compItem itm;
228
+ itm.index = fdinfo->indexByName(tokns[i].c_str());
229
+ m_imple->compItems.push_back(itm);
230
+ m_imple->compFields.push_back(&((*fdinfo)[itm.index]), true /*rePosition*/);
224
231
  }
225
232
  m_imple->row = memoryRecord::create(m_imple->compFields);
226
233
  m_imple->row->addref();
@@ -229,24 +236,32 @@ void recordsetQuery::init(const fielddefs* fdinfo)
229
236
  int index = 0;
230
237
  for (int i = 0; i < (int)tokns.size(); i += 4)
231
238
  {
239
+ recordsetQueryImple::compItem& itm = m_imple->compItems[index];
232
240
  field fd = (*m_imple->row)[index];
233
241
  fd = tokns[i + 2].c_str();
234
242
  bool part = fd.isCompPartAndMakeValue();
235
- unsigned char ct = getFilterLogicTypeCode(tokns[i + 1].c_str());
243
+ itm.compType = getFilterLogicTypeCode(tokns[i + 1].c_str());
236
244
  if (!part)
237
- ct |= CMPLOGICAL_VAR_COMP_ALL;
245
+ itm.compType |= CMPLOGICAL_VAR_COMP_ALL;
246
+ fielddef& fdd = const_cast<fielddef&>(m_imple->compFields[index]);
247
+ fdd.len = compDataLen(m_imple->compFields[index],
248
+ (const uchar_td*)fd.ptr(), part);
249
+ itm.compFunc = fd.getCompFunc(itm.compType);
250
+
251
+ // When use wide string functions, len convert to wide char num.
252
+ if ((itm.compFunc == compiWString) || (itm.compFunc == compWString))
253
+ fdd.len /= sizeof(char16_t);
238
254
 
239
- m_imple->compType.push_back(ct);
240
255
  if (i + 3 < (int)tokns.size())
241
256
  {
242
257
  std::_tstring s = tokns[i + 3];
243
258
  if (s == _T("or"))
244
- m_imple->combine.push_back(eCor);
259
+ itm.combine = eCor;
245
260
  else if (s == _T("and"))
246
- m_imple->combine.push_back(eCand);
261
+ itm.combine = eCand;
247
262
  }
248
263
  else
249
- m_imple->combine.push_back(eCend);
264
+ itm.combine = eCend;
250
265
  ++index;
251
266
  }
252
267
  }
@@ -274,17 +289,18 @@ bool recordsetQuery::isMatch(int ret, unsigned char compType) const
274
289
 
275
290
  bool recordsetQuery::match(const row_ptr row) const
276
291
  {
277
- for (int i = 0; i < (int)m_imple->indexes.size(); ++i)
292
+ for (int i = 0; i < (int)m_imple->compItems.size(); ++i)
278
293
  {
279
- short index = m_imple->indexes[i];
294
+ recordsetQueryImple::compItem& itm = m_imple->compItems[i];
280
295
  bool ret = isMatch(
281
- (*row)[index].comp((*m_imple->row)[i], m_imple->compType[i]),
282
- m_imple->compType[i]);
283
- if (m_imple->combine[i] == eCend)
296
+ itm.compFunc((*row)[itm.index], (*m_imple->row)[i], itm.compType)
297
+ ,itm.compType);
298
+
299
+ if (itm.combine == eCend)
284
300
  return ret;
285
- if (ret && m_imple->combine[i] == eCor)
301
+ if (ret && itm.combine == eCor)
286
302
  return true;
287
- if (!ret && m_imple->combine[i] == eCand)
303
+ if (!ret && itm.combine == eCand)
288
304
  return false;
289
305
  }
290
306
  assert(0);
@@ -299,9 +315,9 @@ inline void setValue(row_ptr& row, int key, double value)
299
315
  // ---------------------------------------------------------------------------
300
316
  // class groupQueryImple
301
317
  // ---------------------------------------------------------------------------
318
+ //#define USE_CLONE_FUNCTION
302
319
  class groupQueryImple : public fieldNames
303
320
  {
304
- // not delete by destructor. simple copy is ok;
305
321
  std::vector<groupFuncBase*> m_funcs;
306
322
 
307
323
  void removeFields(recordsetImple& mdls)
@@ -329,22 +345,39 @@ class groupQueryImple : public fieldNames
329
345
  }
330
346
  }
331
347
  }
332
-
333
348
  if (!enabled)
334
349
  mdls.removeField(i);
335
350
  }
336
351
  }
337
352
 
353
+ void cleanup()
354
+ {
355
+ #ifdef USE_CLONE_FUNCTION
356
+ for (int i=0; i< (int)m_funcs.size() ; ++i)
357
+ delete m_funcs[i];
358
+ #endif
359
+ m_funcs.clear();
360
+ }
361
+
338
362
  public:
339
363
  groupQueryImple() : fieldNames() {}
340
364
 
365
+ ~groupQueryImple() { cleanup(); }
366
+
341
367
  fieldNames& reset()
342
368
  {
343
- m_funcs.clear();
369
+ cleanup();
344
370
  return fieldNames::reset();
345
371
  }
346
372
 
347
- void addFunction(groupFuncBase* func) { m_funcs.push_back(func); }
373
+ void addFunction(groupFuncBase* func)
374
+ {
375
+ #ifdef USE_CLONE_FUNCTION
376
+ m_funcs.push_back(func->clone());
377
+ #else
378
+ m_funcs.push_back(func);
379
+ #endif
380
+ }
348
381
 
349
382
  void grouping(recordsetImple& mdls)
350
383
  {
@@ -361,9 +394,9 @@ public:
361
394
 
362
395
  if (f->resultKey() == (int)mdls.fieldDefs()->size())
363
396
  {
364
- groupFuncBase::value_type dummy = 0;
365
- mdls.appendField(f->resultName(), getFieldType(dummy),
366
- sizeof(dummy));
397
+ groupFuncBase::numeric_type dummy = 0;
398
+ mdls.appendField(f->resultName(), f->resultType(),
399
+ f->resultLen());
367
400
  }
368
401
  }
369
402
 
@@ -389,11 +422,20 @@ public:
389
422
  recordsetImple c(mdls);
390
423
 
391
424
  clear(mdls);
425
+
392
426
  for (int i = 0; i < (int)index.size(); ++i)
393
427
  {
394
428
  recordsetImple::row_type cur = c.getRow(index[i]);
429
+
395
430
  for (int j = 0; j < (int)m_funcs.size(); ++j)
396
- setValue(cur, m_funcs[j]->resultKey(), m_funcs[j]->result(i));
431
+ {
432
+ if (m_funcs[j]->resultType() == ft_float)
433
+ setValue(cur, m_funcs[j]->resultKey(), m_funcs[j]->numericResult(i));
434
+ else
435
+ memcpy((*cur)[m_funcs[j]->resultKey()].ptr() ,
436
+ m_funcs[j]->stringResult(i),
437
+ m_funcs[j]->resultLen());
438
+ }
397
439
  mdls.push_back(cur);
398
440
  }
399
441
  removeFields(mdls);
@@ -486,39 +528,122 @@ int groupQuery::functionCount() const
486
528
  // ---------------------------------------------------------------------------
487
529
  // class groupFuncBaseImple
488
530
  // ---------------------------------------------------------------------------
531
+
489
532
  class groupFuncBaseImple
490
533
  {
491
- public:
492
- typedef double value_type;
493
-
494
534
  private:
495
535
  friend class groupQueryImple;
496
536
  fieldNames m_targetNames;
497
537
  std::_tstring m_resultName;
498
538
  int m_resultKey;
499
539
  std::vector<int> m_targetKeys;
540
+ ushort_td m_resultLen;
541
+ uchar_td m_resultType;
542
+ void clearStrings()
543
+ {
544
+ std::vector<unsigned char*>::iterator it = m_strings.begin();
545
+ while (it != m_strings.end())
546
+ delete [] *(it++);
547
+ m_strings.clear();
548
+ }
549
+
550
+ void copyStrings(const std::vector<unsigned char*>& r)
551
+ {
552
+ std::vector<unsigned char*>::const_iterator it = r.begin();
553
+ while (it != r.end())
554
+ {
555
+ unsigned char* p = new unsigned char[m_resultLen];
556
+ memcpy(p, *(it++), m_resultLen);
557
+ m_strings.push_back(p);
558
+ }
559
+ }
500
560
 
501
561
  public:
502
- std::vector<value_type> m_values;
562
+ std::vector<groupFuncBase::numeric_type> m_values;
503
563
  std::vector<__int64> m_counts;
564
+ std::vector<unsigned char*> m_strings;
565
+
566
+ inline groupFuncBaseImple() : m_resultKey(-1),
567
+ m_resultLen(sizeof(double)),
568
+ m_resultType(ft_float)
569
+ {
570
+ }
504
571
 
505
572
  inline groupFuncBaseImple(const fieldNames& targetNames,
506
573
  const _TCHAR* resultName = NULL)
574
+ : m_resultKey(-1),
575
+ m_resultLen(sizeof(double)),
576
+ m_resultType(ft_float)
507
577
  {
508
578
  m_targetNames = targetNames;
509
579
  m_resultName = (m_targetNames.count() &&
510
580
  ((resultName == NULL) || resultName[0] == 0x00))
511
581
  ? targetNames[0]
512
582
  : resultName;
513
- m_values.reserve(10);
514
583
  }
515
584
 
516
- inline void initResultVariable(int index)
585
+ inline groupFuncBaseImple(const groupFuncBaseImple& r)
586
+ : 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),
589
+ m_values(r.m_values), m_counts(r.m_counts)
590
+ {
591
+ copyStrings(r.m_strings);
592
+ }
593
+
594
+ groupFuncBaseImple& operator=(const groupFuncBaseImple& r)
595
+ {
596
+ if (this != &r)
597
+ {
598
+ m_targetNames = r.m_targetNames;
599
+ m_resultName = r.m_resultName;
600
+ m_resultKey = r.m_resultKey;
601
+ m_resultType = r.m_resultType;
602
+ m_resultLen = r.m_resultLen;
603
+ m_values = r.m_values;
604
+ m_counts = r.m_counts;
605
+ m_strings.clear();
606
+ copyStrings(r.m_strings);
607
+ }
608
+ return *this;
609
+ }
610
+
611
+ ~groupFuncBaseImple()
612
+ {
613
+ clearStrings();
614
+ }
615
+
616
+ inline void setStringResultType(ushort_td len, uchar_td type)
617
+ {
618
+ m_resultType = type;
619
+ m_resultLen = len;
620
+ }
621
+
622
+ inline uchar_td resultType() { return m_resultType; }
623
+
624
+ inline ushort_td resultLen() { return m_resultLen; }
625
+
626
+ inline void appendStringBuffer(int index)
517
627
  {
518
- std::vector<value_type>::iterator it = m_values.begin();
628
+ unsigned char* p = new unsigned char[m_resultLen];
629
+ memset(p, 0, m_resultLen);
630
+ std::vector<unsigned char*>::iterator it = m_strings.begin();
519
631
  if (index)
520
632
  it += index;
521
- m_values.insert(it, 0.0f);
633
+ m_strings.insert(it, p);
634
+ }
635
+
636
+ inline void initResultVariable(int index)
637
+ {
638
+ if (m_resultType == ft_float)
639
+ {
640
+ std::vector<groupFuncBase::numeric_type>::iterator it = m_values.begin();
641
+ if (index)
642
+ it += index;
643
+ m_values.insert(it, 0.0f);
644
+ }
645
+ else
646
+ appendStringBuffer(index);
522
647
  }
523
648
 
524
649
  inline void init(const fielddefs* fdinfo)
@@ -533,8 +658,6 @@ public:
533
658
  m_resultKey = (int)fdinfo->size();
534
659
  }
535
660
 
536
- inline groupFuncBaseImple() { m_values.reserve(10); }
537
-
538
661
  inline fieldNames& targetNames() const
539
662
  {
540
663
  return (fieldNames&)m_targetNames;
@@ -551,12 +674,12 @@ public:
551
674
 
552
675
  inline int resultKey() const { return m_resultKey; }
553
676
 
554
- inline void reset() { m_values.clear(); };
555
-
556
- inline value_type result(int groupIndex) const
677
+ inline void reset()
557
678
  {
558
- return m_values[groupIndex];
559
- };
679
+ m_values.clear();
680
+ m_counts.clear();
681
+ clearStrings();
682
+ }
560
683
 
561
684
  inline int targetKey(size_t index) const
562
685
  {
@@ -570,7 +693,7 @@ public:
570
693
  // ---------------------------------------------------------------------------
571
694
  // class groupFuncBase
572
695
  // ---------------------------------------------------------------------------
573
- groupFuncBase::groupFuncBase() : m_imple(new groupFuncBaseImple())
696
+ groupFuncBase::groupFuncBase() : recordsetQuery(), m_imple(new groupFuncBaseImple())
574
697
  {
575
698
  }
576
699
 
@@ -609,7 +732,7 @@ void groupFuncBase::doCalc(const row_ptr& row, int groupIndex)
609
732
  {
610
733
  }
611
734
 
612
- void groupFuncBase::init(const fielddefs* fdinfo)
735
+ void groupFuncBase::doInit(const fielddefs* fdinfo)
613
736
  {
614
737
  if (whereTokens() != 0)
615
738
  recordsetQuery::init(fdinfo);
@@ -617,6 +740,11 @@ void groupFuncBase::init(const fielddefs* fdinfo)
617
740
  m_imple->init(fdinfo);
618
741
  }
619
742
 
743
+ void groupFuncBase::init(const fielddefs* fdinfo)
744
+ {
745
+ doInit(fdinfo);
746
+ }
747
+
620
748
  groupFuncBase& groupFuncBase::operator=(const recordsetQuery& v)
621
749
  {
622
750
  recordsetQuery::operator=(v);
@@ -644,6 +772,12 @@ int groupFuncBase::resultKey() const
644
772
  }
645
773
 
646
774
  void groupFuncBase::reset()
775
+ {
776
+ recordsetQuery::reset();
777
+ doReset();
778
+ }
779
+
780
+ void groupFuncBase::doReset()
647
781
  {
648
782
  m_imple->reset();
649
783
  }
@@ -660,9 +794,24 @@ void groupFuncBase::operator()(const row_ptr& row, int index, bool insert)
660
794
  doCalc(row, index);
661
795
  }
662
796
 
663
- groupFuncBase::value_type groupFuncBase::result(int groupIndex) const
797
+ groupFuncBase::numeric_type groupFuncBase::numericResult(int groupIndex) const
664
798
  {
665
- return m_imple->result(groupIndex);
799
+ return m_imple->m_values[groupIndex];
800
+ }
801
+
802
+ unsigned char* groupFuncBase::stringResult(int groupIndex) const
803
+ {
804
+ return m_imple->m_strings[groupIndex];
805
+ }
806
+
807
+ ushort_td groupFuncBase::resultLen() const
808
+ {
809
+ return m_imple->resultLen();
810
+ }
811
+
812
+ uchar_td groupFuncBase::resultType() const
813
+ {
814
+ return m_imple->resultType();
666
815
  }
667
816
 
668
817
  // ---------------------------------------------------------------------------
@@ -680,7 +829,7 @@ sum::sum(const fieldNames& targetNames, const _TCHAR* resultName)
680
829
 
681
830
  void sum::doCalc(const row_ptr& row, int index)
682
831
  {
683
- value_type tmp = 0;
832
+ numeric_type tmp = 0;
684
833
  for (int i = 0; i < m_imple->targetKeys(); ++i)
685
834
  m_imple->m_values[index] +=
686
835
  fieldValue((*row)[m_imple->targetKey(i)], tmp);
@@ -688,7 +837,7 @@ void sum::doCalc(const row_ptr& row, int index)
688
837
 
689
838
  groupFuncBase* sum::clone()
690
839
  {
691
- groupFuncBase* p = new sum();
840
+ sum* p = new sum();
692
841
  *p = *this;
693
842
  return p;
694
843
  }
@@ -713,7 +862,7 @@ void count::doCalc(const row_ptr& row, int index)
713
862
 
714
863
  groupFuncBase* count::clone()
715
864
  {
716
- groupFuncBase* p = new count();
865
+ count* p = new count();
717
866
  *p = *this;
718
867
  return p;
719
868
  }
@@ -743,14 +892,14 @@ void avg::doCalc(const row_ptr& row, int index)
743
892
  m_imple->m_counts[index] = m_imple->m_counts[index] + 1;
744
893
  }
745
894
 
746
- avg::value_type avg::result(int index) const
895
+ avg::numeric_type avg::numericResult(int index) const
747
896
  {
748
897
  return m_imple->m_values[index] / m_imple->m_counts[index];
749
898
  }
750
899
 
751
900
  groupFuncBase* avg::clone()
752
901
  {
753
- groupFuncBase* p = new avg();
902
+ avg* p = new avg();
754
903
  *p = *this;
755
904
  return p;
756
905
  }
@@ -770,7 +919,7 @@ min::min(const fieldNames& targetNames, const _TCHAR* resultName)
770
919
 
771
920
  void min::doCalc(const row_ptr& row, int index)
772
921
  {
773
- value_type tmp = 0;
922
+ numeric_type tmp = 0;
774
923
  for (int i = 0; i < m_imple->targetKeys(); ++i)
775
924
  {
776
925
  tmp = fieldValue((*row)[m_imple->targetKey(i)], tmp);
@@ -782,11 +931,22 @@ void min::doCalc(const row_ptr& row, int index)
782
931
 
783
932
  groupFuncBase* min::clone()
784
933
  {
785
- groupFuncBase* p = new min();
934
+ min* p = new min();
786
935
  *p = *this;
787
936
  return p;
788
937
  }
789
938
 
939
+ min& min::operator=(const min& r)
940
+ {
941
+ if (this != &r)
942
+ {
943
+ m_flag = r.m_flag;
944
+ groupFuncBase::operator=(r);
945
+ }
946
+ return *this;
947
+
948
+ }
949
+
790
950
  // ---------------------------------------------------------------------------
791
951
  // class max
792
952
  // ---------------------------------------------------------------------------
@@ -802,7 +962,7 @@ max::max(const fieldNames& targetNames, const _TCHAR* resultName)
802
962
 
803
963
  void max::doCalc(const row_ptr& row, int index)
804
964
  {
805
- value_type tmp = 0;
965
+ numeric_type tmp = 0;
806
966
  for (int i = 0; i < m_imple->targetKeys(); ++i)
807
967
  {
808
968
  tmp = fieldValue((*row)[m_imple->targetKey(i)], tmp);
@@ -814,11 +974,130 @@ void max::doCalc(const row_ptr& row, int index)
814
974
 
815
975
  groupFuncBase* max::clone()
816
976
  {
817
- groupFuncBase* p = new max();
977
+ max* p = new max();
978
+ *p = *this;
979
+ return p;
980
+ }
981
+
982
+ max& max::operator=(const max& r)
983
+ {
984
+ if (this != &r)
985
+ {
986
+ m_flag = r.m_flag;
987
+ groupFuncBase::operator=(r);
988
+ }
989
+ return *this;
990
+ }
991
+
992
+ // ---------------------------------------------------------------------------
993
+ // class last
994
+ // ---------------------------------------------------------------------------
995
+ last* last::create(const fieldNames& targetNames, const _TCHAR* resultName)
996
+ {
997
+ return new last(targetNames, resultName);
998
+ }
999
+
1000
+ last::last(const fieldNames& targetNames, const _TCHAR* resultName)
1001
+ : groupFuncBase(targetNames, resultName)
1002
+ {
1003
+
1004
+ }
1005
+
1006
+ void last::doInit(const fielddefs* fdinfo)
1007
+ {
1008
+ groupFuncBase::doInit(fdinfo);
1009
+ int size = m_imple->targetKeys();
1010
+ if (size)
1011
+ {
1012
+ const fielddef& fd = (*fdinfo)[m_imple->targetKey(0)];
1013
+ if (fd.isStringType() && !fd.isBlob())
1014
+ m_imple->setStringResultType(fd.len, fd.type);
1015
+ }
1016
+ }
1017
+
1018
+ void last::doCalc(const row_ptr& row, int index)
1019
+ {
1020
+ if (m_imple->targetKeys())
1021
+ {
1022
+ numeric_type tmp = 0;
1023
+ if (m_imple->resultType() == ft_float)
1024
+ m_imple->m_values[index] =
1025
+ fieldValue((*row)[m_imple->targetKey(0)], tmp);
1026
+ else
1027
+ {
1028
+ ushort_td len = m_imple->resultLen();
1029
+ unsigned char* p = m_imple->m_strings[index];
1030
+ memcpy(p, (*row)[m_imple->targetKey(0)].ptr(), len);
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ groupFuncBase* last::clone()
1036
+ {
1037
+ last* p = new last();
1038
+ *p = *this;
1039
+ return p;
1040
+ }
1041
+
1042
+ // ---------------------------------------------------------------------------
1043
+ // class first
1044
+ // ---------------------------------------------------------------------------
1045
+ first* first::create(const fieldNames& targetNames, const _TCHAR* resultName)
1046
+ {
1047
+ return new first(targetNames, resultName);
1048
+ }
1049
+
1050
+ first::first(const fieldNames& targetNames, const _TCHAR* resultName)
1051
+ : last(targetNames, resultName),m_readed(false)
1052
+ {
1053
+
1054
+ }
1055
+
1056
+ void first::doCalc(const row_ptr& row, int index)
1057
+ {
1058
+ if (m_readed == false)
1059
+ {
1060
+ if (m_imple->targetKeys())
1061
+ {
1062
+ numeric_type tmp = 0;
1063
+ if (m_imple->resultType() == ft_float)
1064
+ m_imple->m_values[index] =
1065
+ fieldValue((*row)[m_imple->targetKey(0)], tmp);
1066
+ else
1067
+ {
1068
+ ushort_td len = m_imple->resultLen();
1069
+ unsigned char* p = m_imple->m_strings[index];
1070
+ memcpy(p, (*row)[m_imple->targetKey(0)].ptr(), len);
1071
+ }
1072
+ }
1073
+ m_readed = true;
1074
+ }
1075
+ }
1076
+
1077
+ groupFuncBase* first::clone()
1078
+ {
1079
+ first* p = new first();
818
1080
  *p = *this;
819
1081
  return p;
820
1082
  }
821
1083
 
1084
+ void first::doReset()
1085
+ {
1086
+ m_readed = false;
1087
+ groupFuncBase::reset();
1088
+ }
1089
+
1090
+ first& first::operator=(const first& r)
1091
+ {
1092
+ if (this != &r)
1093
+ {
1094
+ m_readed = r.m_readed;
1095
+ last::operator=(r);
1096
+ }
1097
+ return *this;
1098
+ }
1099
+
1100
+
822
1101
  } // namespace client
823
1102
  } // namespace tdap
824
1103
  } // namespace protocol