28 #include <NdbError.hpp>
30 #include "helpers.hpp"
31 #include "string_helpers.hpp"
33 #include "CrundNdbApiOperations.hpp"
43 using utils::toString;
62 #define ABORT_NDB_ERROR(error) \
65 sprintf(l, "%d", __LINE__); \
67 sprintf(c, "%d", error.code); \
68 cout << endl << "!!! error in " << __FILE__ \
69 << ", line: " << l << "," << endl; \
70 cout << " error code: " << c \
71 << ", error msg: " << error.message << "." << endl; \
75 #define VERIFY(cond) \
76 if (cond); else ABORT_ERROR("wrong data; verification failed")
83 CrundModel::init(
Ndb* ndb)
88 if ((table_A = dict->
getTable(
"a")) == NULL)
90 if ((column_A_id = table_A->
getColumn(
"id")) == NULL)
92 if ((column_A_cint = table_A->
getColumn(
"cint")) == NULL)
94 if ((column_A_clong = table_A->
getColumn(
"clong")) == NULL)
96 if ((column_A_cfloat = table_A->
getColumn(
"cfloat")) == NULL)
98 if ((column_A_cdouble = table_A->
getColumn(
"cdouble")) == NULL)
102 if ((table_B0 = dict->
getTable(
"b0")) == NULL)
104 if ((column_B0_id = table_B0->
getColumn(
"id")) == NULL)
106 if ((column_B0_cint = table_B0->
getColumn(
"cint")) == NULL)
108 if ((column_B0_clong = table_B0->
getColumn(
"clong")) == NULL)
110 if ((column_B0_cfloat = table_B0->
getColumn(
"cfloat")) == NULL)
112 if ((column_B0_cdouble = table_B0->
getColumn(
"cdouble")) == NULL)
114 if ((column_B0_a_id = table_B0->
getColumn(
"a_id")) == NULL)
116 if ((column_B0_cvarbinary_def = table_B0->
getColumn(
"cvarbinary_def")) == NULL)
118 if ((column_B0_cvarchar_def = table_B0->
getColumn(
"cvarchar_def")) == NULL)
122 if ((idx_B0_a_id = dict->
getIndex(
"I_B0_FK",
"b0")) == NULL)
126 attr_id = column_A_id->getAttrId();
127 if (attr_id != column_B0_id->getAttrId())
128 ABORT_ERROR(
"attribute id mismatch");
129 attr_cint = column_A_cint->getAttrId();
130 if (attr_cint != column_B0_cint->getAttrId())
131 ABORT_ERROR(
"attribute id mismatch");
132 attr_clong = column_A_clong->getAttrId();
133 if (attr_clong != column_B0_clong->getAttrId())
134 ABORT_ERROR(
"attribute id mismatch");
135 attr_cfloat = column_A_cfloat->getAttrId();
136 if (attr_cfloat != column_B0_cfloat->getAttrId())
137 ABORT_ERROR(
"attribute id mismatch");
138 attr_cdouble = column_A_cdouble->getAttrId();
139 if (attr_cdouble != column_B0_cdouble->getAttrId())
140 ABORT_ERROR(
"attribute id mismatch");
143 attr_B0_a_id = column_B0_a_id->getAttrId();
144 attr_B0_cvarbinary_def = column_B0_cvarbinary_def->getAttrId();
145 attr_B0_cvarchar_def = column_B0_cvarchar_def->getAttrId();
148 attr_idx_B0_a_id = idx_B0_a_id->
getColumn(0)->getAttrId();
174 CrundNdbApiOperations::init(
const char* mgmd_conn_str)
176 assert(mgmd == NULL);
177 assert(mgmd_conn_str);
181 <<
"initializing NDBAPI ..." << flush;
182 int stat = ndb_init();
184 ABORT_ERROR(
"ndb_init() returned: " << stat);
185 cout <<
" [ok]" << endl;
188 cout <<
"creating cluster connection ..." << flush;
189 assert(mgmd_conn_str);
191 cout <<
" [ok]" << endl;
194 cout <<
"connecting to mgmd ..." << flush;
195 const int retries = 0;
197 const int verbose = 1;
199 if (mgmd->
connect(retries, delay, verbose) != 0)
200 ABORT_ERROR(
"mgmd@" << mgmd_conn_str <<
" was not ready within "
201 << (retries * delay) <<
"s.");
202 cout <<
" [ok: " << mgmd_conn_str <<
"]" << endl;
206 CrundNdbApiOperations::close()
208 assert(mgmd != NULL);
210 cout <<
"closing cluster connection ..." << flush;
213 cout <<
" [ok]" << endl;
216 cout <<
"closing NDBAPI ... " << flush;
218 cout <<
" [ok]" << endl;
222 CrundNdbApiOperations::initConnection(
const char* catalog,
const char* schema,
225 assert(mgmd != NULL);
228 assert(model == NULL);
231 cout <<
"waiting for data nodes ..." << flush;
232 const int initial_wait = 10;
233 const int final_wait = 0;
236 ABORT_ERROR(
"data nodes were not ready within "
237 << (initial_wait + final_wait) <<
"s.");
238 cout <<
" [ok]" << endl;
241 cout <<
"connecting to database ..." << flush;
242 ndb =
new Ndb(mgmd, catalog, schema);
243 const int max_no_tx = 10;
246 if (ndb->
init(max_no_tx) != 0)
248 cout <<
" [ok: " << catalog <<
"." << schema <<
"]" << endl;
250 cout <<
"caching metadata ..." << flush;
254 cout <<
" [ok]" << endl;
256 cout <<
"using lock mode for reads ..." << flush;
257 ndbOpLockMode = defaultLockMode;
259 switch (defaultLockMode) {
261 lm =
"LM_CommittedRead";
271 lm =
"LM_CommittedRead";
274 cout <<
" [ok: " + lm +
"]" << endl;
278 CrundNdbApiOperations::closeConnection()
280 assert(mgmd != NULL);
283 assert(model != NULL);
285 cout <<
"clearing metadata cache ..." << flush;
288 cout <<
" [ok]" << endl;
290 cout <<
"closing database connection ..." << flush;
294 cout <<
" [ok]" << endl;
298 CrundNdbApiOperations::beginTransaction()
309 CrundNdbApiOperations::executeOperations()
320 CrundNdbApiOperations::commitTransaction()
331 CrundNdbApiOperations::closeTransaction()
344 CrundNdbApiOperations::clearData()
346 cout <<
"deleting all rows ..." << flush;
347 const bool batch =
true;
349 delByScan(model->table_B0, delB0, batch);
350 cout <<
" [B0: " << toString(delB0) << flush;
352 delByScan(model->table_A, delA, batch);
353 cout <<
", A: " << toString(delA) <<
"]" << endl;
367 return (i.id < j.id);
371 getCommonAB(
const CommonAB*
const ab)
373 Int32 cint = ab->cint;
374 Int64 clong = ab->clong;
375 VERIFY(clong == cint);
376 float cfloat = ab->cfloat;
377 VERIFY(cfloat == cint);
378 double cdouble = ab->cdouble;
379 VERIFY(cdouble == cint);
384 static const char*
const astring1 =
"i";
385 static const char*
const astring10 =
"xxxxxxxxxx";
386 static const char*
const astring100 =
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
387 static const char*
const astring1000 =
"mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
389 static inline const char*
390 selectString(
int length)
394 case 1:
return astring1;
395 case 10:
return astring10;
396 case 100:
return astring100;
397 case 1000:
return astring1000;
407 bool setAttrs,
bool batch)
410 for (
int i = from; i <=
to; i++) {
419 if (op->
equal(model->attr_id, (Int32)i) != 0)
422 if (op->
setValue(model->attr_cint, (Int32)-i) != 0)
424 if (op->
setValue(model->attr_clong, (Int64)-i) != 0)
426 if (op->
setValue(model->attr_cfloat, (
float)-i) != 0)
428 if (op->
setValue(model->attr_cdouble, (
double)-i) != 0)
453 const int scan_flags = 0;
454 const int parallel = 0;
455 const int batch_ = 0;
456 if (op->
readTuples(lock_mode, scan_flags, parallel, batch_) != 0)
465 const bool allowFetch =
true;
466 const bool forceSend =
false;
467 while ((stat = op->
nextResult(allowFetch, forceSend)) == 0) {
477 }
while ((stat = op->
nextResult(!allowFetch, forceSend)) == 0);
490 ABORT_ERROR(
"stat == " + stat);
493 ABORT_ERROR(
"stat == " + stat);
496 const bool forceSend_ =
false;
497 const bool releaseOp =
false;
498 op->
close(forceSend_, releaseOp);
511 for (
int i = from; i <=
to; i++) {
520 if (op->
equal(model->attr_id, (Int32)i) != 0)
537 for (
int i = from; i <=
to; i++) {
546 if (op->
equal(model->attr_id, (Int32)i) != 0)
548 if (op->
setValue(model->attr_cint, (Int32)i) != 0)
550 if (op->
setValue(model->attr_clong, (Int64)i) != 0)
552 if (op->
setValue(model->attr_cfloat, (
float)i) != 0)
554 if (op->
setValue(model->attr_cdouble, (
double)i) != 0)
571 const int count = (to - from) + 1;
577 for (
int i = from; i <=
to; i++, pab++) {
586 if (op->
equal(model->attr_id, (Int32)i) != 0)
590 if (op->
getValue(model->attr_id, (
char*)&pab->id) == NULL)
592 if (op->
getValue(model->attr_cint, (
char*)&pab->cint) == NULL)
594 if (op->
getValue(model->attr_clong, (
char*)&pab->clong) == NULL)
596 if (op->
getValue(model->attr_cfloat, (
char*)&pab->cfloat) == NULL)
598 if (op->
getValue(model->attr_cdouble, (
char*)&pab->cdouble) == NULL)
610 for (
int i = from; i <=
to; i++, pab++) {
615 Int32 j = getCommonAB(pab);
637 VERIFY(clong == cint);
639 VERIFY(cfloat == cint);
641 VERIFY(cdouble == cint);
651 const int count = (to - from) + 1;
657 for (
int i = from; i <=
to; i++, pab++) {
666 if (op->
equal(model->attr_id, (Int32)i) != 0)
670 if ((pab->id = op->
getValue(model->attr_id, NULL)) == NULL)
672 if ((pab->cint = op->
getValue(model->attr_cint, NULL)) == NULL)
674 if ((pab->clong = op->
getValue(model->attr_clong, NULL)) == NULL)
676 if ((pab->cfloat = op->
getValue(model->attr_cfloat, NULL)) == NULL)
678 if ((pab->cdouble = op->
getValue(model->attr_cdouble, NULL)) == NULL)
690 for (
int i = from; i <=
to; i++, pab++) {
695 Int32 j = getCommonAB(pab);
706 int from,
int to,
bool batch,
int length)
708 setVar(table, model->attr_B0_cvarbinary_def,
709 from, to, batch, selectString(length));
714 int from,
int to,
bool batch,
int length)
716 setVar(table, model->attr_B0_cvarchar_def,
717 from, to, batch, selectString(length));
722 int from,
int to,
bool batch,
int length)
724 getVar(table, model->attr_B0_cvarbinary_def,
725 from, to, batch, selectString(length));
730 int from,
int to,
bool batch,
int length)
732 getVar(table, model->attr_B0_cvarchar_def,
733 from, to, batch, selectString(length));
739 bool batch,
const char* str)
744 size_t slen = strlen(str);
746 size_t sbuf = 1 + slen;
749 buf =
new char[sbuf];
751 memcpy(buf + 1, str, slen);
758 for (
int i = from; i <=
to; i++) {
767 if (op->
equal(model->attr_id, (Int32)i) != 0)
769 if (op->
setValue(attr_cvar, buf) != 0)
788 bool batch,
const char* str)
793 const int count = (to - from) + 1;
794 size_t slen = strlen(str);
795 const size_t sline = (1 + slen);
796 const size_t sbuf = count * sline;
797 char*
const buf =
new char[sbuf];
807 for (
int i = from; i <=
to; i++, s += sline) {
816 if (op->
equal(model->attr_id, (Int32)1) != 0)
820 if (op->
getValue(attr_cvar, (
char*)s) == NULL)
829 assert(s == buf + sbuf);
833 for (
int i = from; i <=
to; i++, s += sline) {
839 const size_t n = s[0];
843 memmove(s, s + 1, n);
847 VERIFY(strcmp(s, str) == 0);
849 assert(s == buf + sbuf);
856 CrundNdbApiOperations::setB0ToA(
int nOps,
bool batch)
859 for (
int i = 1; i <= nOps; i++) {
868 if (op->
equal(model->attr_id, (Int32)i) != 0)
872 int a_id = ((i - 1) % nOps) + 1;
873 if (op->
setValue(model->attr_B0_a_id, (Int32)a_id) != 0)
885 CrundNdbApiOperations::nullB0ToA(
int nOps,
bool batch)
888 for (
int i = 1; i <= nOps; i++) {
897 if (op->
equal(model->attr_id, (Int32)i) != 0)
901 if (op->
setValue(model->attr_B0_a_id, (
char*)NULL) != 0)
913 CrundNdbApiOperations::navB0ToA(
int nOps,
bool batch)
921 for (
int i = 1; i <= nOps; i++, pab++) {
933 if (op->
equal(model->attr_id, (Int32)i) != 0)
937 if (op->
getValue(model->attr_B0_a_id, (
char*)&a_id) == NULL)
952 assert(a_id == ((i - 1) % nOps) + 1);
953 if (op->
equal(model->attr_id, a_id) != 0)
957 if (op->
getValue(model->attr_id, (
char*)&pab->id) == NULL)
959 if (op->
getValue(model->attr_cint, (
char*)&pab->cint) == NULL)
961 if (op->
getValue(model->attr_clong, (
char*)&pab->clong) == NULL)
963 if (op->
getValue(model->attr_cfloat, (
char*)&pab->cfloat) == NULL)
965 if (op->
getValue(model->attr_cdouble, (
char*)&pab->cdouble) == NULL)
978 for (
int i = 1; i <= nOps; i++, pab++) {
981 VERIFY(
id == ((i - 1) % nOps) + 1);
983 Int32 j = getCommonAB(pab);
993 CrundNdbApiOperations::navB0ToAalt(
int nOps,
bool batch)
996 Int32*
const a_id =
new Int32[nOps];
1000 Int32* pa_id = a_id;
1001 for (
int i = 1; i <= nOps; i++) {
1010 if (op->
equal(model->attr_id, (Int32)i) != 0)
1014 if (op->
getValue(model->attr_B0_a_id, (
char*)pa_id++) == NULL)
1019 executeOperations();
1021 executeOperations();
1029 for (
int i = 1; i <= nOps; i++, pa_id++, pab++) {
1038 assert(*pa_id == ((i - 1) % nOps) + 1);
1039 if (op->
equal(model->attr_id, (Int32)*pa_id) != 0)
1043 if (op->
getValue(model->attr_id, (
char*)&pab->id) == NULL)
1045 if (op->
getValue(model->attr_cint, (
char*)&pab->cint) == NULL)
1047 if (op->
getValue(model->attr_clong, (
char*)&pab->clong) == NULL)
1049 if (op->
getValue(model->attr_cfloat, (
char*)&pab->cfloat) == NULL)
1051 if (op->
getValue(model->attr_cdouble, (
char*)&pab->cdouble) == NULL)
1056 executeOperations();
1058 commitTransaction();
1066 for (
int i = 1; i <= nOps; i++, pab++) {
1069 VERIFY(
id == ((i - 1) % nOps) + 1);
1071 Int32 j = getCommonAB(pab);
1081 CrundNdbApiOperations::navAToB0(
int nOps,
bool forceSend)
1092 for (
int i = 1; i <= nOps; i++) {
1110 if (op->
setBound(model->attr_idx_B0_a_id,
1115 if (op->
getValue(model->attr_id, (
char*)&h.id) == NULL)
1117 if (op->
getValue(model->attr_cint, (
char*)&h.cint) == NULL)
1119 if (op->
getValue(model->attr_clong, (
char*)&h.clong) == NULL)
1121 if (op->
getValue(model->attr_cfloat, (
char*)&h.cfloat) == NULL)
1123 if (op->
getValue(model->attr_cdouble, (
char*)&h.cdouble) == NULL)
1127 executeOperations();
1131 const bool allowFetch =
true;
1132 while ((stat = op->
nextResult(allowFetch, forceSend)) == 0) {
1133 assert(ab <= pab && pab < ab + nOps);
1141 commitTransaction();
1144 assert(pab == ab + nOps);
1148 vector<CommonAB> b(ab, ab + nOps);
1149 sort(b.begin(), b.end(),
compare);
1150 vector<CommonAB>::const_iterator it = b.begin();
1151 for (
int i = 1; i <= nOps; i++, it++) {
1152 Int32
id = getCommonAB(&it[0]);
1162 CrundNdbApiOperations::navAToB0alt(
int nOps,
bool forceSend)
1165 const int nmscans = (nOps < 256 ? nOps : 256);
1177 while (a_id <= nOps) {
1181 for (
int i = 0; i < nmscans; i++) {
1188 if (op[i]->readTuples(ndbOpLockMode) != 0)
1199 if (op[i]->setBound(model->attr_idx_B0_a_id,
1204 if (op[i]->getValue(model->attr_id, (
char*)&h.id) == NULL)
1206 if (op[i]->getValue(model->attr_cint, (
char*)&h.cint) == NULL)
1208 if (op[i]->getValue(model->attr_clong, (
char*)&h.clong) == NULL)
1210 if (op[i]->getValue(model->attr_cfloat, (
char*)&h.cfloat) == NULL)
1212 if (op[i]->getValue(model->attr_cdouble, (
char*)&h.cdouble) == NULL)
1218 executeOperations();
1221 for (
int i = 0; i < nmscans; i++) {
1224 const bool allowFetch =
true;
1225 while ((stat = op[i]->nextResult(allowFetch, forceSend)) == 0) {
1226 assert(ab <= pab && pab < ab + nOps);
1238 commitTransaction();
1241 assert(a_id == nOps + 1);
1242 assert(pab == ab + nOps);
1246 vector<CommonAB> b(ab, ab + nOps);
1247 sort(b.begin(), b.end(),
compare);
1248 vector<CommonAB>::const_iterator it = b.begin();
1249 for (
int i = 1; i <= nOps; i++, it++) {
1250 Int32
id = getCommonAB(&it[0]);