transactd 3.6.1 → 3.7.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.
- 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();
|