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
@@ -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