transactd 3.6.1 → 3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/common/{tdclc_32_3_6.dll → tdclc_32_3_7.dll} +0 -0
- data/bin/common/{tdclc_64_3_6.dll → tdclc_64_3_7.dll} +0 -0
- data/build/swig/ruby/tdclrb_wrap.cpp +125 -17
- data/build/tdclc/tdclc.cbproj +1 -1
- data/build/tdclc/tdclc.rc +4 -4
- data/build/tdclcpp/tdclcpp.rc +4 -4
- data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
- data/build/tdclrb/tdclrb.rc +4 -4
- data/source/bzs/db/protocol/tdap/client/field.cpp +24 -0
- data/source/bzs/db/protocol/tdap/client/field.h +2 -0
- data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +243 -59
- data/source/bzs/db/protocol/tdap/client/groupQuery.h +8 -0
- data/source/bzs/db/protocol/tdap/client/memRecord.cpp +19 -6
- data/source/bzs/db/protocol/tdap/client/memRecord.h +10 -1
- data/source/bzs/db/protocol/tdap/client/recordset.cpp +17 -0
- data/source/bzs/db/protocol/tdap/client/recordset.h +3 -0
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +131 -30
- data/source/bzs/db/protocol/tdap/client/table.cpp +11 -2
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +1 -0
- data/source/bzs/db/protocol/tdap/tdapcapi.h +5 -5
- data/source/bzs/test/tdclatl/test_v3.js +22 -0
- data/source/bzs/test/tdclphp/transactd_v3_Test.php +35 -0
- data/source/bzs/test/tdclrb/transactd_v3_spec.rb +40 -0
- data/source/bzs/test/trdclengn/testField.h +320 -0
- data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +9 -0
- data/source/global/tdclatl/Recordset.cpp +44 -2
- data/source/global/tdclatl/Recordset.h +6 -2
- data/source/global/tdclatl/tdclatl.idl +5 -1
- metadata +4 -4
@@ -226,32 +226,111 @@ bool fieldValues::isNull(int index) const
|
|
226
226
|
}
|
227
227
|
|
228
228
|
|
229
|
+
struct recordCompItem
|
230
|
+
{
|
231
|
+
judgeFunc isMatchFunc;
|
232
|
+
comp1Func compFunc;
|
233
|
+
short index;
|
234
|
+
short indexTmp; // For join match. converted field index
|
235
|
+
short cmpIndex; // For CMPLOGICAL_FIELD only
|
236
|
+
ushort_td cmpLen;
|
237
|
+
uchar_td compType;
|
238
|
+
char combine;
|
239
|
+
struct
|
240
|
+
{
|
241
|
+
bool nullable : 1;
|
242
|
+
bool nulllog : 1; // condition has isNull or isNotNull
|
243
|
+
};
|
244
|
+
};
|
245
|
+
|
246
|
+
inline char getCombine(const std::vector<std::_tstring>& tokns, int index)
|
247
|
+
{
|
248
|
+
if (index + 3 < (int)tokns.size())
|
249
|
+
{
|
250
|
+
std::_tstring s = tokns[index + 3];
|
251
|
+
if (s == _T("or"))
|
252
|
+
return eCor;
|
253
|
+
else if (s == _T("and"))
|
254
|
+
return eCand;
|
255
|
+
}
|
256
|
+
return eCend;
|
257
|
+
}
|
258
|
+
|
259
|
+
inline uchar_td getCompType(const _TCHAR* v, bool compField, bool part)
|
260
|
+
{
|
261
|
+
|
262
|
+
uchar_td compType = getFilterLogicTypeCode(v);
|
263
|
+
if (compField)
|
264
|
+
compType |= CMPLOGICAL_FIELD;
|
265
|
+
if (!part)
|
266
|
+
compType |= CMPLOGICAL_VAR_COMP_ALL;
|
267
|
+
return compType;
|
268
|
+
}
|
269
|
+
|
270
|
+
inline bool getNullLog(uchar_td compType)
|
271
|
+
{
|
272
|
+
uchar_td log = (compType & 0xf);
|
273
|
+
return ((log == eIsNull) || (log == eIsNotNull));
|
274
|
+
}
|
275
|
+
|
276
|
+
inline comp1Func getCompFunc2(const fielddef& fdd, uchar_td compType)
|
277
|
+
{
|
278
|
+
uchar_td type = fdd.type;
|
279
|
+
if (fdd.isLegacyTimeFormat())
|
280
|
+
{
|
281
|
+
if (type == ft_mytime) type = ft_mytime_num_cmp;
|
282
|
+
if (type == ft_mydatetime) type = ft_mydatetime_num_cmp;
|
283
|
+
if (type == ft_mytimestamp) type = ft_mytimestamp_num_cmp;
|
284
|
+
}
|
285
|
+
return getCompFunc(type, fdd.len, compType,
|
286
|
+
fdd.varLenBytes() + fdd.blobLenBytes());
|
287
|
+
}
|
288
|
+
|
289
|
+
inline short getIndex(const fielddefs* fdinfo, const std::_tstring& v)
|
290
|
+
{
|
291
|
+
short index = fdinfo->indexByName(v);
|
292
|
+
if (index == -1)
|
293
|
+
THROW_BZS_ERROR_WITH_MSG(_T("recordsetQuery:Invalid field name ")
|
294
|
+
+ std::_tstring(v));
|
295
|
+
return index;
|
296
|
+
}
|
297
|
+
|
298
|
+
inline bool isSingedInteger(uchar_td type)
|
299
|
+
{
|
300
|
+
return ((type == ft_integer) || (type == ft_autoinc));
|
301
|
+
}
|
302
|
+
|
303
|
+
inline bool isUnsingedInteger(uchar_td type)
|
304
|
+
{
|
305
|
+
return ((type == ft_logical) || (type == ft_uinteger) || (type == ft_set) ||
|
306
|
+
(type == ft_bit) || (type == ft_enum) || (type == ft_autoIncUnsigned) ||
|
307
|
+
(type == ft_myyear));
|
308
|
+
}
|
309
|
+
|
310
|
+
bool canDirectComp(const fielddef& l, const fielddef& r)
|
311
|
+
{
|
312
|
+
if (l.type == r.type && l.charsetIndex() == r.charsetIndex())
|
313
|
+
return true;
|
314
|
+
if (isSingedInteger(l.type) == isSingedInteger(r.type)) return true;
|
315
|
+
if (isUnsingedInteger(l.type) == isUnsingedInteger(r.type)) return true;
|
316
|
+
return false;
|
317
|
+
}
|
318
|
+
|
319
|
+
|
229
320
|
// ---------------------------------------------------------------------------
|
230
321
|
// struct recordsetQueryImple
|
231
322
|
// ---------------------------------------------------------------------------
|
232
323
|
struct recordsetQueryImple
|
233
324
|
{
|
234
|
-
row_ptr row;
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
comp1Func compFunc;
|
239
|
-
short index;
|
240
|
-
short cmpIndex; // For CMPLOGICAL_FIELD only
|
241
|
-
uchar_td compType;
|
242
|
-
char combine;
|
243
|
-
struct
|
244
|
-
{
|
245
|
-
bool nullable : 1;
|
246
|
-
bool nulllog : 1;
|
247
|
-
};
|
248
|
-
};
|
249
|
-
std::vector<compItem> compItems;
|
250
|
-
fielddefs compFields;
|
325
|
+
row_ptr row; // For matchBy condition values or join target of converted fields
|
326
|
+
row_ptr joinRow; // For join target row
|
327
|
+
std::vector<recordCompItem> compItems; // condition parms
|
328
|
+
fielddefs compFields; // condition fields
|
251
329
|
short endIndex;
|
330
|
+
short matchHint;
|
252
331
|
bool mysqlnull;
|
253
332
|
|
254
|
-
recordsetQueryImple() : row(NULL),mysqlnull(false) {}
|
333
|
+
recordsetQueryImple() : row(NULL), joinRow(NULL), mysqlnull(false) {}
|
255
334
|
recordsetQueryImple(const recordsetQueryImple& r)
|
256
335
|
: row(r.row), compItems(r.compItems), compFields(r.compFields), mysqlnull(r.mysqlnull)
|
257
336
|
{
|
@@ -304,31 +383,39 @@ recordsetQuery::~recordsetQuery()
|
|
304
383
|
delete m_imple;
|
305
384
|
}
|
306
385
|
|
386
|
+
void recordsetQuery::createTempRecord()
|
387
|
+
{
|
388
|
+
m_imple->compFields.calcFieldPos(0 /*startIndex*/, true);
|
389
|
+
m_imple->row = memoryRecord::create(m_imple->compFields);
|
390
|
+
m_imple->row->addref();
|
391
|
+
m_imple->row->setRecordData(autoMemory::create(), 0, 0, &m_imple->endIndex, true);
|
392
|
+
}
|
393
|
+
/*
|
394
|
+
init for matchBy
|
395
|
+
*/
|
307
396
|
void recordsetQuery::init(const fielddefs* fdinfo)
|
308
397
|
{
|
309
398
|
m_imple->mysqlnull = fdinfo->mysqlnullEnable();
|
310
399
|
const std::vector<std::_tstring>& tokns = getWheres();
|
311
|
-
m_imple->
|
400
|
+
m_imple->row = NULL;
|
312
401
|
m_imple->compItems.clear();
|
402
|
+
m_imple->compFields.clear();
|
313
403
|
for (int i = 0; i < (int)tokns.size(); i += 4)
|
314
404
|
{
|
315
|
-
|
316
|
-
itm.
|
317
|
-
|
318
|
-
|
319
|
-
itm.
|
405
|
+
recordCompItem itm;
|
406
|
+
itm.indexTmp = -1;
|
407
|
+
itm.index = getIndex(fdinfo, tokns[i]);
|
408
|
+
itm.nullable = (*fdinfo)[itm.index].isNullable() & m_imple->mysqlnull;
|
409
|
+
itm.cmpLen = (*fdinfo)[itm.index].len;
|
320
410
|
m_imple->compItems.push_back(itm);
|
321
411
|
m_imple->compFields.push_back(&((*fdinfo)[itm.index]));
|
322
412
|
}
|
323
|
-
|
324
|
-
m_imple->row = memoryRecord::create(m_imple->compFields);
|
325
|
-
m_imple->row->addref();
|
326
|
-
m_imple->row->setRecordData(autoMemory::create(), 0, 0, &m_imple->endIndex, true);
|
413
|
+
createTempRecord();
|
327
414
|
|
328
415
|
int index = 0;
|
329
416
|
for (int i = 0; i < (int)tokns.size(); i += 4)
|
330
417
|
{
|
331
|
-
|
418
|
+
recordCompItem& itm = m_imple->compItems[index];
|
332
419
|
field fd = (*m_imple->row)[index];
|
333
420
|
|
334
421
|
std::_tstring value = tokns[i + 2];
|
@@ -337,66 +424,163 @@ void recordsetQuery::init(const fielddefs* fdinfo)
|
|
337
424
|
{
|
338
425
|
value.erase(value.begin());
|
339
426
|
value.erase(value.end() - 1);
|
340
|
-
itm.cmpIndex = fdinfo
|
341
|
-
if (itm.cmpIndex == -1)
|
342
|
-
THROW_BZS_ERROR_WITH_MSG(_T("recordsetQuery:Invalid field name ") + value);
|
427
|
+
itm.cmpIndex = getIndex(fdinfo, value);
|
343
428
|
}
|
344
429
|
else
|
345
430
|
fd = value.c_str();
|
346
431
|
bool part = fd.isCompPartAndMakeValue();
|
347
|
-
itm.compType =
|
348
|
-
|
349
|
-
itm.compType |= CMPLOGICAL_FIELD;
|
350
|
-
if (!part)
|
351
|
-
itm.compType |= CMPLOGICAL_VAR_COMP_ALL;
|
352
|
-
eCompType log = (eCompType)(itm.compType & 0xf);
|
353
|
-
itm.nulllog = ((log == eIsNull) || (log == eIsNotNull));
|
432
|
+
itm.compType = getCompType(tokns[i + 1].c_str(), compField, part);
|
433
|
+
itm.nulllog = (m_imple->mysqlnull && getNullLog(itm.compType));
|
354
434
|
fielddef& fdd = const_cast<fielddef&>(m_imple->compFields[index]);
|
355
435
|
fdd.len = m_imple->compFields[index].compDataLen((const uchar_td*)fd.ptr(), part);
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
436
|
+
itm.compFunc = getCompFunc2(fdd, itm.compType);
|
437
|
+
itm.isMatchFunc = getJudgeFunc((eCompType)itm.compType);
|
438
|
+
itm.combine = getCombine(tokns, i);
|
439
|
+
itm.cmpLen = fdd.len;
|
440
|
+
if (itm.compType & CMPLOGICAL_FIELD)
|
441
|
+
{ // No field type convert
|
442
|
+
const fielddef& fdr = m_imple->compFields[itm.cmpIndex];
|
443
|
+
itm.cmpLen = std::min(fdd.len, fdr.len);
|
362
444
|
}
|
445
|
+
++index;
|
446
|
+
}
|
447
|
+
}
|
363
448
|
|
364
|
-
|
365
|
-
|
449
|
+
/*
|
450
|
+
init for join
|
451
|
+
*/
|
452
|
+
void recordsetQuery::init(const fielddefs* fdinfo, const fielddefs* rfdinfo)
|
453
|
+
{
|
454
|
+
m_imple->mysqlnull = fdinfo->mysqlnullEnable();
|
455
|
+
const std::vector<std::_tstring>& tokns = getWheres();
|
456
|
+
m_imple->row = NULL;
|
457
|
+
m_imple->compItems.clear();
|
458
|
+
m_imple->compFields.clear();
|
459
|
+
for (int i = 0; i < (int)tokns.size(); i += 4)
|
460
|
+
{
|
461
|
+
recordCompItem itm;
|
462
|
+
itm.indexTmp = -1;
|
463
|
+
itm.index = getIndex(fdinfo, tokns[i]);
|
464
|
+
itm.cmpIndex = getIndex(rfdinfo, tokns[i+2]);
|
465
|
+
itm.nullable = true;//(*fdinfo)[itm.index].isNullable() | (*rfdinfo)[itm.cmpIndex].isNullable();
|
466
|
+
itm.compType = getCompType(tokns[i + 1].c_str(), true, false);
|
467
|
+
itm.nulllog = getNullLog(itm.compType);
|
468
|
+
if (itm.nulllog)
|
469
|
+
THROW_BZS_ERROR_WITH_MSG(_T("recordsetQuery:Join can not use null compare. "));
|
470
|
+
|
366
471
|
itm.isMatchFunc = getJudgeFunc((eCompType)itm.compType);
|
472
|
+
itm.combine = getCombine(tokns, i);
|
473
|
+
|
474
|
+
// different field type
|
475
|
+
const fielddef& fdd = (*fdinfo)[itm.index];
|
476
|
+
const fielddef& fddr = (*rfdinfo)[itm.cmpIndex];
|
477
|
+
if (fdd.isBlob() || fddr.isBlob())
|
478
|
+
THROW_BZS_ERROR_WITH_MSG(_T("recordsetQuery: BLOB or TEXT can not use for join key field. "));
|
479
|
+
if (!canDirectComp(fdd, fddr))
|
480
|
+
{
|
481
|
+
m_imple->compFields.push_back(&fddr);
|
482
|
+
short index = (short)m_imple->compFields.size() - 1;
|
483
|
+
itm.indexTmp = index;
|
484
|
+
if (fdd.isNullable())
|
485
|
+
{
|
486
|
+
fielddef& fd = const_cast<fielddef&>(m_imple->compFields[index]);
|
487
|
+
fd.setNullable(true, fdd.isDefaultNull());
|
488
|
+
}
|
489
|
+
itm.cmpLen = fddr.len;
|
490
|
+
itm.compFunc = getCompFunc2(fddr, itm.compType);
|
491
|
+
|
492
|
+
}else
|
493
|
+
{ // same type
|
494
|
+
const fielddef& fdest = (fdd.len < fddr.len) ? fdd : fddr;
|
495
|
+
itm.cmpLen = fdest.len;
|
496
|
+
itm.compFunc = getCompFunc2(fdest, itm.compType);
|
497
|
+
}
|
498
|
+
m_imple->compItems.push_back(itm);
|
499
|
+
}
|
500
|
+
if (m_imple->compFields.size())
|
501
|
+
createTempRecord();
|
502
|
+
}
|
503
|
+
|
504
|
+
void recordsetQuery::setJoinRow(const row_ptr row)
|
505
|
+
{
|
506
|
+
if (m_imple->row)
|
507
|
+
{
|
508
|
+
// Convert data type
|
509
|
+
for (size_t i = 0; i < m_imple->compItems.size(); ++i)
|
510
|
+
{
|
511
|
+
recordCompItem& itm = m_imple->compItems[i];
|
512
|
+
if (itm.indexTmp != -1)
|
513
|
+
{
|
514
|
+
field f = (*m_imple->row)[itm.indexTmp];
|
515
|
+
const field& fd = (*row)[itm.index];
|
516
|
+
if (fd.isNull())
|
517
|
+
f.setNull(true);
|
518
|
+
else
|
519
|
+
f = fd.c_str();
|
520
|
+
}
|
521
|
+
}
|
522
|
+
}
|
523
|
+
else
|
524
|
+
m_imple->joinRow = row;
|
525
|
+
}
|
367
526
|
|
368
|
-
|
527
|
+
#define HINT_LEFT_NULL 1
|
528
|
+
/*
|
529
|
+
match for join
|
530
|
+
*/
|
531
|
+
bool recordsetQuery::matchJoin(const row_ptr rrow) const
|
532
|
+
{
|
533
|
+
m_imple->matchHint = 0;
|
534
|
+
for (int i = 0; i < (int)m_imple->compItems.size(); ++i)
|
535
|
+
{
|
536
|
+
recordCompItem& itm = m_imple->compItems[i];
|
537
|
+
bool ret;
|
538
|
+
int nullJudge = 2;
|
539
|
+
const field& f = itm.indexTmp == -1 ? (*m_imple->joinRow)[itm.index] : (*m_imple->row)[itm.indexTmp];
|
540
|
+
const field& fr = (*rrow)[itm.cmpIndex];
|
541
|
+
if (itm.nullable)
|
542
|
+
nullJudge = f.nullCompMatch(fr, 0);
|
543
|
+
if (nullJudge < 2)
|
369
544
|
{
|
370
|
-
|
371
|
-
|
372
|
-
itm.combine = eCor;
|
373
|
-
else if (s == _T("and"))
|
374
|
-
itm.combine = eCand;
|
545
|
+
ret = (nullJudge == 0);
|
546
|
+
m_imple->matchHint |= (nullJudge == -1) ? HINT_LEFT_NULL : 0;
|
375
547
|
}
|
376
548
|
else
|
377
|
-
|
378
|
-
|
549
|
+
{
|
550
|
+
nullJudge = itm.compFunc((const char*)f.ptr(), (const char*)fr.ptr(), itm.cmpLen);
|
551
|
+
ret = itm.isMatchFunc(nullJudge);
|
552
|
+
}
|
553
|
+
if (isEndComp(itm.combine, ret)) return ret;
|
379
554
|
}
|
555
|
+
return true;
|
556
|
+
}
|
557
|
+
|
558
|
+
int recordsetQuery::matchStatus() const
|
559
|
+
{
|
560
|
+
if (m_imple->matchHint & HINT_LEFT_NULL && m_imple->compItems.size() == 1)
|
561
|
+
return JOIN_NO_MORERECORD;
|
562
|
+
|
563
|
+
return 0;
|
380
564
|
}
|
381
565
|
|
382
566
|
bool recordsetQuery::match(const row_ptr row) const
|
383
567
|
{
|
384
568
|
for (int i = 0; i < (int)m_imple->compItems.size(); ++i)
|
385
569
|
{
|
386
|
-
|
570
|
+
recordCompItem& itm = m_imple->compItems[i];
|
387
571
|
bool ret;
|
388
572
|
int nullJudge = 2;
|
389
573
|
const field& f = (*row)[itm.index];
|
390
|
-
if (
|
574
|
+
if (itm.nullable || itm.nulllog)
|
391
575
|
nullJudge = f.nullComp((eCompType)(itm.compType & 0xf));
|
392
576
|
if (nullJudge < 2)
|
393
577
|
ret = (nullJudge == 0) ? true : false;
|
394
578
|
else
|
395
579
|
{
|
396
580
|
if (itm.compType & CMPLOGICAL_FIELD)
|
397
|
-
ret = itm.isMatchFunc(itm.compFunc((const char*)f.ptr(), (const char*)(*row)[itm.cmpIndex].ptr(),
|
581
|
+
ret = itm.isMatchFunc(itm.compFunc((const char*)f.ptr(), (const char*)(*row)[itm.cmpIndex].ptr(), itm.cmpLen));
|
398
582
|
else
|
399
|
-
ret = itm.isMatchFunc(itm.compFunc((const char*)f.ptr(), (const char*)((*m_imple->row)[i].ptr()),
|
583
|
+
ret = itm.isMatchFunc(itm.compFunc((const char*)f.ptr(), (const char*)((*m_imple->row)[i].ptr()), itm.cmpLen));
|
400
584
|
}
|
401
585
|
if (isEndComp(itm.combine, ret)) return ret;
|
402
586
|
}
|
@@ -31,6 +31,8 @@ namespace tdap
|
|
31
31
|
namespace client
|
32
32
|
{
|
33
33
|
|
34
|
+
#define JOIN_NO_MORERECORD 1
|
35
|
+
|
34
36
|
class DLLLIB fieldNames
|
35
37
|
{
|
36
38
|
|
@@ -108,8 +110,14 @@ class DLLLIB recordsetQuery : protected query
|
|
108
110
|
friend class recordsetImple;
|
109
111
|
|
110
112
|
struct recordsetQueryImple* m_imple;
|
113
|
+
|
114
|
+
void createTempRecord();
|
111
115
|
void init(const fielddefs* fdinfo);
|
116
|
+
void init(const fielddefs* fdinfo, const fielddefs* rfdinfo);
|
112
117
|
bool match(const row_ptr row) const;
|
118
|
+
bool matchJoin(const row_ptr rrow) const;
|
119
|
+
void setJoinRow(const row_ptr row);
|
120
|
+
int matchStatus() const;
|
113
121
|
|
114
122
|
public:
|
115
123
|
recordsetQuery();
|
@@ -36,7 +36,7 @@ namespace client
|
|
36
36
|
{
|
37
37
|
|
38
38
|
autoMemory::autoMemory() : refarymem(), ptr(0), endFieldIndex(NULL), size(0),
|
39
|
-
owner(false)
|
39
|
+
usedIndex(0), owner(false)
|
40
40
|
{
|
41
41
|
}
|
42
42
|
|
@@ -45,7 +45,7 @@ void autoMemory::setParams(unsigned char* p, size_t s, short* endIndex, bool own
|
|
45
45
|
if (owner)
|
46
46
|
{
|
47
47
|
delete[] ptr;
|
48
|
-
delete endFieldIndex;
|
48
|
+
delete[] endFieldIndex;
|
49
49
|
}
|
50
50
|
|
51
51
|
ptr = p;
|
@@ -59,11 +59,24 @@ void autoMemory::setParams(unsigned char* p, size_t s, short* endIndex, bool own
|
|
59
59
|
memcpy(ptr, p, size);
|
60
60
|
else
|
61
61
|
memset(ptr, 0, size + 1);
|
62
|
-
endFieldIndex = new short;
|
62
|
+
endFieldIndex = new short[JOINLIMIT_PER_RECORD];
|
63
|
+
memset(endFieldIndex, 0, sizeof(short) * JOINLIMIT_PER_RECORD);
|
63
64
|
if (endIndex != NULL)
|
64
|
-
|
65
|
+
endFieldIndex[usedIndex] = *endIndex;
|
65
66
|
}
|
66
|
-
|
67
|
+
}
|
68
|
+
|
69
|
+
short* autoMemory::appendEndFieldIndex(short value)
|
70
|
+
{
|
71
|
+
assert(owner);
|
72
|
+
endFieldIndex[++usedIndex] = value;
|
73
|
+
return endFieldIndex + (usedIndex);
|
74
|
+
}
|
75
|
+
|
76
|
+
void autoMemory::assignEndFieldIndex(short* p)
|
77
|
+
{
|
78
|
+
assert(owner);
|
79
|
+
memcpy(endFieldIndex, p, sizeof(short) * JOINLIMIT_PER_RECORD);
|
67
80
|
}
|
68
81
|
|
69
82
|
autoMemory::~autoMemory()
|
@@ -71,7 +84,7 @@ autoMemory::~autoMemory()
|
|
71
84
|
if (owner)
|
72
85
|
{
|
73
86
|
delete[] ptr;
|
74
|
-
delete endFieldIndex;
|
87
|
+
delete[] endFieldIndex;
|
75
88
|
}
|
76
89
|
}
|
77
90
|
|
@@ -44,9 +44,12 @@ public:
|
|
44
44
|
void setParams(unsigned char* p, size_t s, short* endIndex, bool own);
|
45
45
|
|
46
46
|
autoMemory& operator=(const bzs::db::protocol::tdap::client::autoMemory& p);
|
47
|
+
short* appendEndFieldIndex(short value);
|
48
|
+
void assignEndFieldIndex(short* p);
|
47
49
|
unsigned char* ptr;
|
48
50
|
short* endFieldIndex;
|
49
|
-
unsigned int size
|
51
|
+
unsigned int size;
|
52
|
+
unsigned char usedIndex;
|
50
53
|
bool owner ;
|
51
54
|
static autoMemory* create(int n);
|
52
55
|
static autoMemory* create();
|
@@ -134,6 +137,12 @@ class DLLLIB memoryRecord : public fieldsBase
|
|
134
137
|
}
|
135
138
|
}
|
136
139
|
|
140
|
+
inline void setInvalidMemblockLast()
|
141
|
+
{
|
142
|
+
int num = memBlockSize() -1;
|
143
|
+
m_InvalidFlags |= ((2L << num) | 1L);
|
144
|
+
}
|
145
|
+
|
137
146
|
void releaseMemory();
|
138
147
|
|
139
148
|
protected:
|
@@ -180,6 +180,18 @@ recordset& recordset::reverse()
|
|
180
180
|
return *this;
|
181
181
|
}
|
182
182
|
|
183
|
+
recordset& recordset::join(const recordset& rs, recordsetQuery& rq)
|
184
|
+
{
|
185
|
+
m_imple->nestedLoopJoin(*rs.m_imple, rq, true);
|
186
|
+
return *this;
|
187
|
+
}
|
188
|
+
|
189
|
+
recordset& recordset::outerJoin(const recordset& rs, recordsetQuery& rq)
|
190
|
+
{
|
191
|
+
m_imple->nestedLoopJoin(*rs.m_imple, rq, false);
|
192
|
+
return *this;
|
193
|
+
}
|
194
|
+
|
183
195
|
void recordset::reserve(size_t size)
|
184
196
|
{
|
185
197
|
m_imple->reserve(size);
|
@@ -190,6 +202,11 @@ void recordset::appendField(const _TCHAR* name, int type, short len)
|
|
190
202
|
m_imple->appendField(name, type, len);
|
191
203
|
}
|
192
204
|
|
205
|
+
void recordset::appendField(const fielddef& fd)
|
206
|
+
{
|
207
|
+
m_imple->appendField(fd);
|
208
|
+
}
|
209
|
+
|
193
210
|
recordset& recordset::operator+=(const recordset& r)
|
194
211
|
{
|
195
212
|
if (r.size() == 0)
|
@@ -71,8 +71,11 @@ public:
|
|
71
71
|
const _TCHAR* name7 = NULL, const _TCHAR* name8 = NULL);
|
72
72
|
recordset& orderBy(const sortFields& orders);
|
73
73
|
recordset& reverse();
|
74
|
+
recordset& join(const recordset& rs, recordsetQuery& rq);
|
75
|
+
recordset& outerJoin(const recordset& rs, recordsetQuery& rq);
|
74
76
|
void reserve(size_t size);
|
75
77
|
void appendField(const _TCHAR* name, int type, short len);
|
78
|
+
void appendField(const fielddef& fd);
|
76
79
|
recordset& operator+=(const recordset& r);
|
77
80
|
void release();
|
78
81
|
static recordset* create();
|