transactd 2.4.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CMakeLists.txt +1 -1
- data/README-JA.md +52 -529
- data/README.md +52 -523
- data/bin/common/tdclc_32_3_0.dll +0 -0
- data/bin/common/tdclc_64_3_0.dll +0 -0
- data/build/common/system.cmake +2 -1
- data/build/common/transactd_cl_common.cmake +3 -6
- data/build/swig/ruby/ruby.swg +85 -28
- data/build/swig/ruby/tdclrb_wrap.cpp +3195 -1578
- data/build/swig/tdcl.i +161 -5
- data/build/tdclc/CMakeLists.txt +1 -0
- data/build/tdclc/tdclc.cbproj +7 -1
- data/build/tdclc/tdclc.rc +4 -4
- data/build/tdclcpp/tdclcpp.rc +4 -4
- data/build/tdclcpp/tdclcpp_bc.cbproj +2 -5
- data/build/tdclrb/tdclrb.rc +4 -4
- data/source/bzs/db/blobStructs.h +1 -1
- data/source/bzs/db/engine/mysql/database.cpp +199 -74
- data/source/bzs/db/engine/mysql/database.h +47 -18
- data/source/bzs/db/engine/mysql/dbManager.cpp +1 -0
- data/source/bzs/db/engine/mysql/mysqlInternal.h +32 -8
- data/source/bzs/db/protocol/tdap/btrDate.cpp +110 -75
- data/source/bzs/db/protocol/tdap/btrDate.h +46 -21
- data/source/bzs/db/protocol/tdap/client/activeTable.cpp +18 -18
- data/source/bzs/db/protocol/tdap/client/activeTable.h +25 -25
- data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
- data/source/bzs/db/protocol/tdap/client/client.cpp +6 -5
- data/source/bzs/db/protocol/tdap/client/client.h +82 -15
- data/source/bzs/db/protocol/tdap/client/database.cpp +531 -142
- data/source/bzs/db/protocol/tdap/client/database.h +19 -6
- data/source/bzs/db/protocol/tdap/client/dbDef.cpp +461 -408
- data/source/bzs/db/protocol/tdap/client/dbDef.h +11 -17
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +61 -13
- data/source/bzs/db/protocol/tdap/client/field.cpp +1592 -1398
- data/source/bzs/db/protocol/tdap/client/field.h +110 -121
- data/source/bzs/db/protocol/tdap/client/fields.h +40 -10
- data/source/bzs/db/protocol/tdap/client/filter.h +69 -55
- data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +296 -164
- data/source/bzs/db/protocol/tdap/client/groupQuery.h +77 -25
- data/source/bzs/db/protocol/tdap/client/memRecord.cpp +31 -13
- data/source/bzs/db/protocol/tdap/client/memRecord.h +31 -21
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +69 -24
- data/source/bzs/db/protocol/tdap/client/nsTable.h +3 -1
- data/source/bzs/db/protocol/tdap/client/recordset.cpp +1 -0
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +46 -27
- data/source/bzs/db/protocol/tdap/client/request.h +2 -1
- data/source/bzs/db/protocol/tdap/client/serializer.cpp +44 -9
- data/source/bzs/db/protocol/tdap/client/serializer.h +1 -1
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +182 -76
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +23 -12
- data/source/bzs/db/protocol/tdap/client/stringConverter.h +8 -10
- data/source/bzs/db/protocol/tdap/client/table.cpp +172 -93
- data/source/bzs/db/protocol/tdap/client/table.h +112 -37
- data/source/bzs/db/protocol/tdap/client/trdboostapi.h +17 -0
- data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +0 -1
- data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +0 -2
- data/source/bzs/db/protocol/tdap/client/trdormapi.h +1 -1
- data/source/bzs/db/protocol/tdap/fieldComp.h +698 -14
- data/source/bzs/db/protocol/tdap/myDateTime.cpp +723 -307
- data/source/bzs/db/protocol/tdap/myDateTime.h +294 -0
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +164 -54
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +6 -3
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +133 -550
- data/source/bzs/db/protocol/tdap/mysql/request.h +6 -5
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +217 -82
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +1 -1
- data/source/bzs/db/protocol/tdap/tdapRequest.h +4 -9
- data/source/bzs/db/protocol/tdap/tdapSchema.cpp +808 -17
- data/source/bzs/db/protocol/tdap/tdapSchema.h +656 -164
- data/source/bzs/db/protocol/tdap/tdapcapi.h +130 -28
- data/source/bzs/db/protocol/tdap/uri.h +40 -32
- data/source/bzs/db/transactd/connManager.cpp +1 -1
- data/source/bzs/db/transactd/transactd.cpp +7 -0
- data/source/bzs/env/compiler.h +107 -94
- data/source/bzs/env/crosscompile.cpp +24 -12
- data/source/bzs/env/crosscompile.h +75 -6
- data/source/bzs/env/mbcswchrLinux.cpp +2 -2
- data/source/bzs/env/tcharMinGW.h +4 -0
- data/source/bzs/example/changeSchema.cpp +22 -17
- data/source/bzs/example/queryData.cpp +4 -0
- data/source/bzs/netsvc/client/iconnection.h +3 -1
- data/source/bzs/netsvc/client/tcpClient.h +10 -3
- data/source/bzs/rtl/stringBuffers.cpp +7 -0
- data/source/bzs/test/tdclatl/bench_query_atl.js +6 -0
- data/source/bzs/test/tdclatl/bench_tdclatl.js +8 -1
- data/source/bzs/test/tdclatl/test_query_atl.js +22 -2
- data/source/bzs/test/tdclatl/test_v3.js +1017 -0
- data/source/bzs/test/tdclphp/transactd_Test.php +55 -21
- data/source/bzs/test/tdclphp/transactd_datetime_Test.php +0 -5
- data/source/bzs/test/tdclphp/transactd_pool_Test.php +2 -0
- data/source/bzs/test/tdclphp/transactd_v3_Test.php +743 -0
- data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -5
- data/source/bzs/test/tdclrb/transactd_pool_spec.rb +2 -0
- data/source/bzs/test/tdclrb/transactd_spec.rb +39 -16
- data/source/bzs/test/tdclrb/transactd_v3_spec.rb +748 -0
- data/source/bzs/test/transactdBench/transactdBench.cpp +55 -58
- data/source/bzs/test/transactdBench/transactdBench2.cpp +1 -3
- data/source/bzs/test/trdclengn/testField.h +3305 -0
- data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +1050 -0
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +112 -190
- data/source/bzs/test/trdclengn/testbase.h +137 -0
- data/source/global/ormsrcgen/srcgen.cpp +23 -12
- data/source/global/ormsrcgen/template/ormDataClass_template.h +2 -0
- data/source/global/querystmts/querystmts.cpp +2 -3
- data/source/global/tdclatl/Bitset.cpp +38 -0
- data/source/global/tdclatl/Bitset.h +63 -0
- data/source/global/tdclatl/Database.cpp +59 -18
- data/source/global/tdclatl/Database.h +7 -4
- data/source/global/tdclatl/DbDef.cpp +6 -6
- data/source/global/tdclatl/DbDef.h +2 -1
- data/source/global/tdclatl/Field.cpp +112 -0
- data/source/global/tdclatl/Field.h +19 -5
- data/source/global/tdclatl/FieldDef.cpp +137 -16
- data/source/global/tdclatl/FieldDef.h +18 -2
- data/source/global/tdclatl/FieldDefs.cpp +54 -1
- data/source/global/tdclatl/FieldDefs.h +3 -0
- data/source/global/tdclatl/GroupQuery.cpp +8 -8
- data/source/global/tdclatl/QueryBase.cpp +65 -0
- data/source/global/tdclatl/QueryBase.h +10 -0
- data/source/global/tdclatl/Record.cpp +33 -2
- data/source/global/tdclatl/Record.h +3 -1
- data/source/global/tdclatl/RecordsetQuery.cpp +42 -0
- data/source/global/tdclatl/RecordsetQuery.h +8 -0
- data/source/global/tdclatl/Table.cpp +127 -3
- data/source/global/tdclatl/Table.h +10 -1
- data/source/global/tdclatl/TableDef.cpp +41 -8
- data/source/global/tdclatl/TableDef.h +7 -2
- data/source/global/tdclatl/activeTable.cpp +40 -71
- data/source/global/tdclatl/resource.h +0 -0
- data/source/global/tdclatl/tdclatl.idl +222 -28
- data/source/linux/tchar.h +100 -96
- data/transactd.gemspec +2 -2
- metadata +13 -11
- data/BUILD_UNIX-JA.md +0 -161
- data/BUILD_WIN-JA.md +0 -326
- data/README_ORMSRCGEN-JA.md +0 -115
- data/README_ORMSRCGEN.md +0 -118
- data/RELEASE_NOTE-JA.md +0 -356
- data/RELEASE_NOTE.md +0 -360
- data/bin/common/tdclc_32_2_4.dll +0 -0
- data/bin/common/tdclc_64_2_4.dll +0 -0
- 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()),
|
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)
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
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->
|
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)
|
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)
|
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->
|
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 (
|
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].
|
727
|
+
return (*m_rs)[rowNum].nullPtr(col);
|
709
728
|
}
|
710
729
|
|
711
|
-
inline void multiRecordAlocatorImple::
|
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]].
|
736
|
+
(*m_rs)[map[j]].setInvalidMemblock(v ? m_curFirstField : 0);
|
718
737
|
}
|
719
738
|
else
|
720
|
-
(*m_rs)[row + m_rowOffset].
|
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
|
182
|
+
void serialize(Archive& ar, readStatement& q, const unsigned int version)
|
182
183
|
{
|
183
184
|
boost::serialization::base_object<executable>(q);
|
184
|
-
|
185
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|