transactd 2.4.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +1 -1
  3. data/README-JA.md +52 -529
  4. data/README.md +52 -523
  5. data/bin/common/tdclc_32_3_0.dll +0 -0
  6. data/bin/common/tdclc_64_3_0.dll +0 -0
  7. data/build/common/system.cmake +2 -1
  8. data/build/common/transactd_cl_common.cmake +3 -6
  9. data/build/swig/ruby/ruby.swg +85 -28
  10. data/build/swig/ruby/tdclrb_wrap.cpp +3195 -1578
  11. data/build/swig/tdcl.i +161 -5
  12. data/build/tdclc/CMakeLists.txt +1 -0
  13. data/build/tdclc/tdclc.cbproj +7 -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 -5
  17. data/build/tdclrb/tdclrb.rc +4 -4
  18. data/source/bzs/db/blobStructs.h +1 -1
  19. data/source/bzs/db/engine/mysql/database.cpp +199 -74
  20. data/source/bzs/db/engine/mysql/database.h +47 -18
  21. data/source/bzs/db/engine/mysql/dbManager.cpp +1 -0
  22. data/source/bzs/db/engine/mysql/mysqlInternal.h +32 -8
  23. data/source/bzs/db/protocol/tdap/btrDate.cpp +110 -75
  24. data/source/bzs/db/protocol/tdap/btrDate.h +46 -21
  25. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +18 -18
  26. data/source/bzs/db/protocol/tdap/client/activeTable.h +25 -25
  27. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
  28. data/source/bzs/db/protocol/tdap/client/client.cpp +6 -5
  29. data/source/bzs/db/protocol/tdap/client/client.h +82 -15
  30. data/source/bzs/db/protocol/tdap/client/database.cpp +531 -142
  31. data/source/bzs/db/protocol/tdap/client/database.h +19 -6
  32. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +461 -408
  33. data/source/bzs/db/protocol/tdap/client/dbDef.h +11 -17
  34. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +61 -13
  35. data/source/bzs/db/protocol/tdap/client/field.cpp +1592 -1398
  36. data/source/bzs/db/protocol/tdap/client/field.h +110 -121
  37. data/source/bzs/db/protocol/tdap/client/fields.h +40 -10
  38. data/source/bzs/db/protocol/tdap/client/filter.h +69 -55
  39. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +296 -164
  40. data/source/bzs/db/protocol/tdap/client/groupQuery.h +77 -25
  41. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +31 -13
  42. data/source/bzs/db/protocol/tdap/client/memRecord.h +31 -21
  43. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +1 -1
  44. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
  45. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +69 -24
  46. data/source/bzs/db/protocol/tdap/client/nsTable.h +3 -1
  47. data/source/bzs/db/protocol/tdap/client/recordset.cpp +1 -0
  48. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +46 -27
  49. data/source/bzs/db/protocol/tdap/client/request.h +2 -1
  50. data/source/bzs/db/protocol/tdap/client/serializer.cpp +44 -9
  51. data/source/bzs/db/protocol/tdap/client/serializer.h +1 -1
  52. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +182 -76
  53. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +23 -12
  54. data/source/bzs/db/protocol/tdap/client/stringConverter.h +8 -10
  55. data/source/bzs/db/protocol/tdap/client/table.cpp +172 -93
  56. data/source/bzs/db/protocol/tdap/client/table.h +112 -37
  57. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +17 -0
  58. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +0 -1
  59. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +0 -2
  60. data/source/bzs/db/protocol/tdap/client/trdormapi.h +1 -1
  61. data/source/bzs/db/protocol/tdap/fieldComp.h +698 -14
  62. data/source/bzs/db/protocol/tdap/myDateTime.cpp +723 -307
  63. data/source/bzs/db/protocol/tdap/myDateTime.h +294 -0
  64. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +164 -54
  65. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +6 -3
  66. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +133 -550
  67. data/source/bzs/db/protocol/tdap/mysql/request.h +6 -5
  68. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +217 -82
  69. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +1 -1
  70. data/source/bzs/db/protocol/tdap/tdapRequest.h +4 -9
  71. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +808 -17
  72. data/source/bzs/db/protocol/tdap/tdapSchema.h +656 -164
  73. data/source/bzs/db/protocol/tdap/tdapcapi.h +130 -28
  74. data/source/bzs/db/protocol/tdap/uri.h +40 -32
  75. data/source/bzs/db/transactd/connManager.cpp +1 -1
  76. data/source/bzs/db/transactd/transactd.cpp +7 -0
  77. data/source/bzs/env/compiler.h +107 -94
  78. data/source/bzs/env/crosscompile.cpp +24 -12
  79. data/source/bzs/env/crosscompile.h +75 -6
  80. data/source/bzs/env/mbcswchrLinux.cpp +2 -2
  81. data/source/bzs/env/tcharMinGW.h +4 -0
  82. data/source/bzs/example/changeSchema.cpp +22 -17
  83. data/source/bzs/example/queryData.cpp +4 -0
  84. data/source/bzs/netsvc/client/iconnection.h +3 -1
  85. data/source/bzs/netsvc/client/tcpClient.h +10 -3
  86. data/source/bzs/rtl/stringBuffers.cpp +7 -0
  87. data/source/bzs/test/tdclatl/bench_query_atl.js +6 -0
  88. data/source/bzs/test/tdclatl/bench_tdclatl.js +8 -1
  89. data/source/bzs/test/tdclatl/test_query_atl.js +22 -2
  90. data/source/bzs/test/tdclatl/test_v3.js +1017 -0
  91. data/source/bzs/test/tdclphp/transactd_Test.php +55 -21
  92. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +0 -5
  93. data/source/bzs/test/tdclphp/transactd_pool_Test.php +2 -0
  94. data/source/bzs/test/tdclphp/transactd_v3_Test.php +743 -0
  95. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -5
  96. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +2 -0
  97. data/source/bzs/test/tdclrb/transactd_spec.rb +39 -16
  98. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +748 -0
  99. data/source/bzs/test/transactdBench/transactdBench.cpp +55 -58
  100. data/source/bzs/test/transactdBench/transactdBench2.cpp +1 -3
  101. data/source/bzs/test/trdclengn/testField.h +3305 -0
  102. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +1050 -0
  103. data/source/bzs/test/trdclengn/test_trdclengn.cpp +112 -190
  104. data/source/bzs/test/trdclengn/testbase.h +137 -0
  105. data/source/global/ormsrcgen/srcgen.cpp +23 -12
  106. data/source/global/ormsrcgen/template/ormDataClass_template.h +2 -0
  107. data/source/global/querystmts/querystmts.cpp +2 -3
  108. data/source/global/tdclatl/Bitset.cpp +38 -0
  109. data/source/global/tdclatl/Bitset.h +63 -0
  110. data/source/global/tdclatl/Database.cpp +59 -18
  111. data/source/global/tdclatl/Database.h +7 -4
  112. data/source/global/tdclatl/DbDef.cpp +6 -6
  113. data/source/global/tdclatl/DbDef.h +2 -1
  114. data/source/global/tdclatl/Field.cpp +112 -0
  115. data/source/global/tdclatl/Field.h +19 -5
  116. data/source/global/tdclatl/FieldDef.cpp +137 -16
  117. data/source/global/tdclatl/FieldDef.h +18 -2
  118. data/source/global/tdclatl/FieldDefs.cpp +54 -1
  119. data/source/global/tdclatl/FieldDefs.h +3 -0
  120. data/source/global/tdclatl/GroupQuery.cpp +8 -8
  121. data/source/global/tdclatl/QueryBase.cpp +65 -0
  122. data/source/global/tdclatl/QueryBase.h +10 -0
  123. data/source/global/tdclatl/Record.cpp +33 -2
  124. data/source/global/tdclatl/Record.h +3 -1
  125. data/source/global/tdclatl/RecordsetQuery.cpp +42 -0
  126. data/source/global/tdclatl/RecordsetQuery.h +8 -0
  127. data/source/global/tdclatl/Table.cpp +127 -3
  128. data/source/global/tdclatl/Table.h +10 -1
  129. data/source/global/tdclatl/TableDef.cpp +41 -8
  130. data/source/global/tdclatl/TableDef.h +7 -2
  131. data/source/global/tdclatl/activeTable.cpp +40 -71
  132. data/source/global/tdclatl/resource.h +0 -0
  133. data/source/global/tdclatl/tdclatl.idl +222 -28
  134. data/source/linux/tchar.h +100 -96
  135. data/transactd.gemspec +2 -2
  136. metadata +13 -11
  137. data/BUILD_UNIX-JA.md +0 -161
  138. data/BUILD_WIN-JA.md +0 -326
  139. data/README_ORMSRCGEN-JA.md +0 -115
  140. data/README_ORMSRCGEN.md +0 -118
  141. data/RELEASE_NOTE-JA.md +0 -356
  142. data/RELEASE_NOTE.md +0 -360
  143. data/bin/common/tdclc_32_2_4.dll +0 -0
  144. data/bin/common/tdclc_64_2_4.dll +0 -0
  145. data/source/bzs/test/trdclengn/test_blob.cpp +0 -375
@@ -20,6 +20,7 @@
20
20
  =================================================================*/
21
21
  #include "trdormapi.h"
22
22
  #include "groupQuery.h"
23
+ #include <bzs/rtl/stringBuffers.h>
23
24
  #ifdef _DEBUG
24
25
  #include <iostream>
25
26
  #include <iomanip>
@@ -57,14 +58,14 @@ class dumpRecordset
57
58
 
58
59
  for (size_t col = 0; col < fds.size(); ++col)
59
60
  {
60
- m_widths[col] = std::max(_tcslen(fds[col].name()), m_widths[col]);
61
- m_ailgns[col] = fds[col].isStringType() ? std::ios::left : std::ios::right;
61
+ m_widths[col] = std::max(_tcslen(fds[(short)col].name()), (size_t)4);
62
+ m_ailgns[col] = (fds[(short)col].isStringType() ? std::ios::left : std::ios::right);
62
63
  }
63
64
  for(size_t i = 0; i < rs.size(); ++i)
64
65
  {
65
66
  row& rec = rs[i];
66
67
  for (size_t col = 0; col < fds.size(); ++col)
67
- m_widths[col] = std::max(_tcslen(rec[col].c_str()), m_widths[col]);
68
+ m_widths[col] = std::max(_tcslen(rec[(short)col].c_str()), m_widths[col]);
68
69
  }
69
70
  }
70
71
 
@@ -87,30 +88,39 @@ class dumpRecordset
87
88
  }
88
89
 
89
90
  const _TCHAR* value(const fielddef& fd) {return fd.name();}
90
- const _TCHAR* value(const field& fd) {return fd.c_str();}
91
+ const _TCHAR* value(const field& fd)
92
+ {
93
+ if (fd.isNull())
94
+ return _T("NULL");
95
+ return fd.c_str();
96
+ }
91
97
 
92
98
  template <class T>
93
99
  void printRecord(const T& coll)
94
100
  {
95
101
  std::tcout << _T("|");
96
102
  for (size_t col = 0; col < m_widths.size(); ++col)
97
- printValue(m_widths[col], m_ailgns[col], value(coll[col]));
103
+ printValue(m_widths[col], m_ailgns[col], value(coll[(short)col]));
98
104
  std::tcout << std::endl;
99
105
  }
100
106
  public:
101
107
  void operator()(RS& rs)
102
108
  {
103
- cacheWidthAndAlign(rs);
104
- std::_tstring line = makeLine();
105
- //header
106
- std::tcout << line;
107
- printRecord(*rs.fieldDefs());
108
- std::tcout << line;
109
-
110
- //field value
111
- for(size_t i = 0; i < rs.size(); ++i)
112
- printRecord(rs[i]);
113
- std::tcout << line;
109
+ if (rs.size())
110
+ {
111
+ cacheWidthAndAlign(rs);
112
+ std::_tstring line = makeLine();
113
+ //header
114
+ std::tcout << line;
115
+ printRecord(*rs.fieldDefs());
116
+ std::tcout << line;
117
+
118
+ //field value
119
+ for(size_t i = 0; i < rs.size(); ++i)
120
+ printRecord(rs[i]);
121
+ std::tcout << line;
122
+ }else
123
+ std::tcout << _T("Empty set ") << std::endl;
114
124
  }
115
125
  };
116
126
  #endif
@@ -163,7 +173,8 @@ public:
163
173
  inline unsigned char* ptr(size_t row, int stat);
164
174
  inline void setRowOffset(int v) { m_rowOffset = v; }
165
175
  inline void setJoinType(int v) { m_addType = v; }
166
- inline void setInvalidRecord(size_t row, bool v);
176
+ inline int joinType() const {return m_addType; };
177
+ inline void setInvalidMemblock(size_t row, bool v);
167
178
  inline void setCurFirstField(int v) { m_curFirstField = v; }
168
179
  inline void setJoinRowMap(const std::vector<std::vector<int> >* v)
169
180
  {
@@ -229,7 +240,7 @@ private:
229
240
  m_mra->setRowOffset(0);
230
241
  m_mra->setCurFirstField((int)m_fds->size());
231
242
  if (tb)
232
- m_fds->copyFrom(tb);
243
+ m_fds->addSelectedFields(tb);
233
244
  if (tb && (addtype == mra_nojoin))
234
245
  {
235
246
  const keydef& kd = tb->tableDef()->keyDefs[(int)tb->keyNum()];
@@ -407,11 +418,11 @@ public:
407
418
  std::vector<short> offsetIndex;
408
419
  for (int j = 0; j < (int)m_fds->size(); ++j)
409
420
  {
410
- if (m_fds->operator[](j).blobLenBytes())
421
+ if (blobLenBytes(m_fds->operator[](j)))
411
422
  {
412
423
  blobs.push_back((short)j);
413
424
  unsigned char* p = (unsigned char*)(*m_recordset[0])[j].ptr()
414
- + m_fds->operator[](j).blobLenBytes();
425
+ + blobLenBytes(m_fds->operator[](j));
415
426
  short index = (short)getMemBlockIndex(p);
416
427
  offsetIndex.push_back(index);
417
428
  }
@@ -422,7 +433,8 @@ public:
422
433
  dynamic_cast<memoryRecord*>(m_recordset[i]);
423
434
  memoryRecord* mr = recs + i;
424
435
  p->push_back(mr);
425
- mr->m_invalidRecord = row->m_invalidRecord;
436
+ mr->m_InvalidFlags = row->m_InvalidFlags;
437
+
426
438
  for (int j = 0; j < (int)row->memBlockSize(); ++j)
427
439
  {
428
440
  const autoMemory& mb = row->memBlock(j);
@@ -432,6 +444,7 @@ public:
432
444
  #pragma warn .8072
433
445
  autoMemory* a = amar + amindex;
434
446
  const boost::shared_ptr<autoMemory>& am = p->m_memblock[index];
447
+ // isInvalidRecord will be reset.
435
448
  mr->setRecordData(a, ptr, mb.size, am->endFieldIndex, mb.owner);
436
449
  ++amindex;
437
450
  }
@@ -640,7 +653,7 @@ public:
640
653
  return *this;
641
654
  }
642
655
 
643
- inline void appendField(const _TCHAR* name, int type, short len)
656
+ inline void appendField(const _TCHAR* name, int type, short len, uchar_td decimals=0)
644
657
  {
645
658
  assert(m_fds->size());
646
659
 
@@ -649,8 +662,9 @@ public:
649
662
  fd.len = len;
650
663
  fd.pos = 0;
651
664
  fd.type = type;
665
+ fd.decimals = decimals;
652
666
  fd.setName(name);
653
- if (fd.blobLenBytes())
667
+ if (blobLenBytes(fd))
654
668
  THROW_BZS_ERROR_WITH_MSG(_T("Can not append Blob or Text field."));
655
669
  m_fds->push_back(&fd);
656
670
  if (size())
@@ -673,6 +687,11 @@ public:
673
687
  return *this;
674
688
  }
675
689
 
690
+ inline void clearStringBuffer()
691
+ {
692
+ m_fds->strBufs()->clear();
693
+ }
694
+
676
695
  #ifdef _DEBUG
677
696
  void dump()
678
697
  {
@@ -705,19 +724,19 @@ inline unsigned char* multiRecordAlocatorImple::ptr(size_t row, int stat)
705
724
  int col = (stat == mra_current_block) ? m_curFirstField : 0;
706
725
  size_t rowNum = m_joinRowMap ? (*m_joinRowMap)[row + m_rowOffset][0]
707
726
  : row + m_rowOffset;
708
- return (*m_rs)[rowNum].ptr(col);
727
+ return (*m_rs)[rowNum].nullPtr(col);
709
728
  }
710
729
 
711
- inline void multiRecordAlocatorImple::setInvalidRecord(size_t row, bool v)
730
+ inline void multiRecordAlocatorImple::setInvalidMemblock(size_t row, bool v)
712
731
  {
713
732
  if (m_joinRowMap)
714
733
  {
715
734
  const std::vector<int>& map = (*m_joinRowMap)[row + m_rowOffset];
716
735
  for (int j = 0; j < (int)map.size(); ++j)
717
- (*m_rs)[map[j]].setInvalidRecord(v);
736
+ (*m_rs)[map[j]].setInvalidMemblock(v ? m_curFirstField : 0);
718
737
  }
719
738
  else
720
- (*m_rs)[row + m_rowOffset].setInvalidRecord(v);
739
+ (*m_rs)[row + m_rowOffset].setInvalidMemblock(v ? m_curFirstField : 0);
721
740
  }
722
741
 
723
742
  inline void multiRecordAlocatorImple::duplicateRow(int row, int count)
@@ -18,9 +18,10 @@
18
18
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
19
  02111-1307, USA.
20
20
  ================================================================= */
21
-
21
+ #pragma warning(disable : 4005) //BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT redefine bug
22
22
  #include <bzs/db/protocol/tdap/tdapRequest.h>
23
23
  #include <bzs/netsvc/client/iconnection.h>
24
+ #pragma warning(default : 4005)
24
25
 
25
26
  #ifdef USE_DATA_COMPRESS
26
27
  #include <bzs/rtl/lzss.h>
@@ -66,7 +66,8 @@ BOOST_CLASS_EXPORT_GUID(bzs::db::protocol::tdap::client::reverseOrderStatement,
66
66
 
67
67
  BOOST_CLASS_VERSION(bzs::db::protocol::tdap::client::groupFuncBase, 1)
68
68
  BOOST_CLASS_VERSION(bzs::db::protocol::tdap::client::queryBase, 1)
69
-
69
+ BOOST_CLASS_VERSION(bzs::db::protocol::tdap::client::readStatement, 1)
70
+ BOOST_CLASS_VERSION(bzs::db::protocol::tdap::client::readHasMany, 1)
70
71
  namespace bzs
71
72
  {
72
73
  namespace db
@@ -178,11 +179,15 @@ void serialize(Archive& /*ar*/, reverseOrderStatement& q,
178
179
  }
179
180
 
180
181
  template <class Archive>
181
- void serialize(Archive& ar, readStatement& q, const unsigned int /*version*/)
182
+ void serialize(Archive& ar, readStatement& q, const unsigned int version)
182
183
  {
183
184
  boost::serialization::base_object<executable>(q);
184
- ar& boost::serialization::make_nvp(
185
- "keyFields", boost::serialization::base_object<fieldNames>(q));
185
+ if (version < 1)
186
+ ar& boost::serialization::make_nvp(
187
+ "keyFields", boost::serialization::base_object<fieldNames>(q));
188
+ else
189
+ ar& boost::serialization::make_nvp(
190
+ "keyValues", boost::serialization::base_object<fieldValues>(q));
186
191
  ar& boost::serialization::make_nvp(
187
192
  "query", boost::serialization::base_object<query>(q));
188
193
  ar& boost::serialization::make_nvp("params", *q.internalPtr());
@@ -191,7 +196,6 @@ void serialize(Archive& ar, readStatement& q, const unsigned int /*version*/)
191
196
  template <class Archive>
192
197
  void serialize(Archive& ar, readHasMany& q, const unsigned int /*version*/)
193
198
  {
194
-
195
199
  ar& boost::serialization::make_nvp(
196
200
  "readStatement", boost::serialization::base_object<readStatement>(q));
197
201
  ar& boost::serialization::make_nvp("params", *q.internalPtr());
@@ -286,6 +290,31 @@ void serialize(Archive& ar, fieldNames& q, const unsigned int /*version*/)
286
290
  }
287
291
  }
288
292
 
293
+ template <class Archive>
294
+ void serialize(Archive& ar, fieldValues& q, const unsigned int /*version*/)
295
+ {
296
+ int count = q.count();
297
+ ar& boost::serialization::make_nvp("count", count);
298
+ std::_tstring s;
299
+ bool isNull;
300
+ for (int i = 0; i < count; i++)
301
+ {
302
+ if (Archive::is_loading::value)
303
+ {
304
+ serialize_string(ar, "value", s);
305
+ ar& boost::serialization::make_nvp("isNull", isNull);
306
+ q.addValue(s.c_str(), isNull);
307
+ }
308
+ else
309
+ {
310
+ s = q.getValue(i);
311
+ serialize_string(ar, "value", s);
312
+ isNull = q.isNull(i);
313
+ ar& boost::serialization::make_nvp("isNull", isNull);
314
+ }
315
+ }
316
+ }
317
+
289
318
  template <class Archive>
290
319
  void serialize(Archive& ar, query& q, const unsigned int /*version*/)
291
320
  {
@@ -470,7 +499,10 @@ groupFuncBase& groupByStatement::addFunction(eFunc v,
470
499
  func = new client::sum(targetNames, resultName);
471
500
  break;
472
501
  case fcount:
473
- func = new client::count(resultName);
502
+ if (targetNames.count())
503
+ func = new client::count(targetNames, resultName);
504
+ else
505
+ func = new client::count(resultName);
474
506
  break;
475
507
  case favg:
476
508
  func = new client::avg(targetNames, resultName);
@@ -669,7 +701,7 @@ struct queryStatementImple
669
701
  std::_tstring database;
670
702
  std::_tstring table;
671
703
  int option;
672
- fieldNames* keyFields;
704
+ fieldValues* keyFields;
673
705
  client::query* query;
674
706
  readStatement::eReadType readType;
675
707
  short index;
@@ -707,6 +739,9 @@ struct queryStatementImple
707
739
  const _TCHAR* keys[8] = { NULL };
708
740
  for (int i = 0; i < keyFields->count(); ++i)
709
741
  keys[i] = parent->pv.replace(keyFields->getValue(i));
742
+ for (int i = 0; i < keyFields->count(); ++i)
743
+ if(keyFields->isNull(i))
744
+ keys[i] = NULL;
710
745
 
711
746
  client::query q;
712
747
  client::query* tq = replaceQueryParams(query, q, parent);
@@ -1279,12 +1314,12 @@ void readHasMany::execute(recordset& rs)
1279
1314
 
1280
1315
  for (int i = 0; i < (int)rs.size(); ++i)
1281
1316
  {
1282
- fieldNames::reset();
1317
+ fieldValues::reset();
1283
1318
  // setkey values
1284
1319
  for (int j = 0; j < (int)indexes.size(); ++j)
1285
1320
  {
1286
1321
  const _TCHAR* p = rs[i][indexes[j]].c_str();
1287
- addValue(p);
1322
+ addValue(p, rs[i][indexes[j]].isNull());
1288
1323
  if (j == 0)
1289
1324
  addLogic(getkeyValueColumn(j), _T("="), p);
1290
1325
  else
@@ -150,7 +150,7 @@ public:
150
150
  static reverseOrderStatement* create();
151
151
  };
152
152
 
153
- class DLLLIBSTMT readStatement : public fieldNames,
153
+ class DLLLIBSTMT readStatement : public fieldValues,
154
154
  public query,
155
155
  public executable
156
156
  {